나는 이것이 참조 및 가변 범위 문제라고 생각합니다.

나는 이것이 참조 및 가변 범위 문제라고 생각합니다.

다음은 권장되는 해결 방법입니다. 나는 그것을 실행했고 효과가 있었다.

#!/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

# (my comment) I am assuming an implied exit here

실제로 주석 처리된 명령줄에 터미널에 대한 실제 종료를 입력했습니다.

다음 질문이 주어지면 그것이 무엇이며 왜 작동하는지 이해하지 못합니다.

질문 1 - 주어진 내용:

    trap "exit_handler '${device_name}'" EXIT

${device_name} 주위의 작은 따옴표는 트랩이 시작될 때(핸들러가 종료된 후, "do_something"이 반환되고 로컬 변수 ${device_name}이 더 이상 존재하지 않는 후) 대체가 수행되어야 함을 나타냅니다. , 내 생각에는) 코드에 종료 문이 없고 종료에 대한 명확한 오류 이유가 없기 때문입니다. 대체를 충족하려면 "do_something" 함수가 반환되어야 하며 ${device_name} 변수가 더 이상 존재하지 않아야 합니다. 명령문이 작은따옴표 없이 다음과 같이 다시 코딩되는 경우

    trap "exit_handler ${device_name}" EXIT

종료가 발생하기 훨씬 전에 Trap 문이 실행될 때 대체가 어떻게 발생하는지 명확하게 알 수 있습니다. 여기에 bash 참조가 무엇인지 이해가 안 되나요?

질문 2 – "do_something"에 다음 문장이 주어졌습니다.

    other

"do_something"에 대해 로컬로 간주되고 "other"가 분명히 "do_something"이 아닌 경우 "do_something"에서 호출된 "other" 함수에 ${device_name}의 로컬 값을 사용할 수 있도록 허용하는 특별한 범위 지정 규칙이 있습니까? '뭔가를 해라'의 지역적 가치가 '? 나는 다른 언어의 범위 지정 규칙이 이를 방지한다고 생각합니다. 아래와 같이 ${device_name}을 매개변수로 요구하는 함수 호출(예: 트랩 호출)이 필요합니다.

    other "${device_name}"

"기타"는 지역 변수에 매개변수를 할당해야 합니다.

  local device_name="${1}"

분명히 Bash의 범위 지정을 이해하지 못합니다.

답변1

이 코드를 실행하면,

local device_name="abc"
trap "exit_handler '${device_name}'" EXIT

쉘은 큰따옴표를 보고 $()그 안의 변수와 표현식을 평가합니다.

device_name="abc"
trap "exit_handler 'abc'" EXIT

그런 다음 쉘은 결과를 실행하여 종료 트랩을 설정합니다. (if) 트랩이 트리거되면 exit_handler함수는 단일 3자 인수로 호출됩니다 abc.

당신의 진술,"${device_name} 주위의 작은 따옴표는 (어쨌든 나에게) 트랩을 시작할 때 대체가 이루어져야 함을 나타냅니다."는 올바르지 않습니다. 전체 표현식 주위의 큰따옴표는 쉘이 보고 평가하는 내용을 제어합니다. 문자열 내부의 작은따옴표는 이 시점에서 단지 일반 문자입니다.

$device_name트랩 매개변수의 평가를 지연하려면 작은따옴표로 묶어 전달해야 합니다.

#!/bin/bash

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

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

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

do_something

관련 정보