bash의 트랩 핸들러에 지역 변수를 전달하는 방법

bash의 트랩 핸들러에 지역 변수를 전달하는 방법

bash 함수에 선언된 지역 변수는 호출된 함수에는 표시되지만 트랩 핸들러에는 표시되지 않습니다.

#!/bin/bash

function exit_handler() {
  echo "Exit handler: ${device_name}"
}

function other() {
  echo "Other: ${device_name}"
}

function do_something() {
  local device_name="abc"
  trap exit_handler EXIT
  other
}

do_something

산출:

$ bash test.sh 
Other: abc
Error handler: 

로컬 변수의 값을 트랩 핸들러에 전달하는 가장 좋은 방법은 무엇입니까? 변수가 즉시 확장되는지 아니면 함수의 끝에서 확장되는지(후자가 지역 변수에 대해 가능하지 않은 경우)는 나에게 중요하지 않습니다.

내가 시도한 것:

  1. 변수를 삭제하여 전역 변수로 만듭니다 local. 이 방법은 효과가 있지만 전역 네임스페이스를 오염시키고 싶지 않기 때문에 이 솔루션이 마음에 들지 않습니다.

  2. 변수를 핸들러에 직접 전달합니다.

    function exit_handler() {
      local device_name="${1}"
      echo "Error handler: ${device_name}"
    }
    
    function do_something() {
      local device_name="abc"
      trap exit_handler "${device_name}" EXIT
    }
    

    이것은 작동하지 않습니다 ( invalid signal specification). 값이 신호 이름으로 해석된다고 가정합니다. 신호 이름에서 명령을 분리하는 방법이 있습니까?

  3. 트랩 명령을 작은따옴표로 묶습니다(이는 다음과 같은 이유 때문입니다).shellcheck):

    function exit_handler() {
      local device_name="${1}"
      echo "Exit handler: ${device_name}"
    }
    
    function do_something() {
      local device_name="abc"
      trap 'exit_handler "${device_name}"' EXIT
    }
    

    그러나 이것은 여전히 ​​종료 처리기에서 빈 출력을 제공합니다. 그래서 지역 변수가 충분히 오래 살지 못할 수도 있다고 생각합니다.

답변1

해결 방법 3. 매우 가깝습니다. 함수 컨텍스트에서 변수를 평가해야 합니다.do_something

업데이트된 예는 다음과 같습니다.

#!/bin/bash

function exit_handler() {
  local device_name="${1}"
  echo "Exit handler: ${device_name}"
}

function other() {
  echo "Other: ${device_name}"
}

function do_something() {
  local device_name="abc"
  trap "exit_handler '${device_name}'" EXIT
  other
}

do_something

관련 정보