다음은 BASH 스크립트의 예입니다.
#!/bin/bash
exithdl() {
echo "in exithdl subshell=$BASH_SUBSHELL" >&2
}
trap exithdl EXIT
fun() {
echo "in fun subshell=$BASH_SUBSHELL" >&2
trap -p EXIT >&2
echo "returned from fun"
}
echo "subshell=$BASH_SUBSHELL" >&2
trap -p EXIT >&2
echo "$(fun)" >&2
echo "exiting" >&2
실행되면 다음과 같은 출력이 생성됩니다.
subshell=0
trap -- 'exithdl' EXIT
in fun subshell=1
trap -- 'exithdl' EXIT
returned from fun
exiting
in exithdl subshell=0
서브쉘 0과 1의 명령은 trap -p EXIT >&2
정의된 EXIT 트랩을 표시하지만 이 exithdl
기능은 서브쉘 0이 종료된 후에만 실행됩니다. exithdl
종료 후 서브쉘 1이 실행되지 않도록 하는 방법이 있습니까 ? 즉, fun
이 함수가 EXIT 트랩 없이 서브쉘 1을 결정할 수 있도록 하나 이상의 명령을 추가하는 것이 가능합니까?
예제에서 EXIT 트랩은 하위 쉘 0에 대해 정의되지만 하위 쉘 1에 대해서는 정의되지 않습니다. 이 trap -p EXIT
명령은 두 서브셸 모두에서 실행될 때 정확히 동일한 출력을 표시합니다. 따라서 trap -p EXIT
특정 서브쉘에 트랩이 있는지 확인하는 데에는 사용할 수 없다고 가정합니다. 나는 trap -p EXIT
명령이 실행될 때 EXIT 트랩의 존재를 표시한다는 것을 인정 fun
하지만, fun이 반환될 때 EXIT 트랩이 실행된다면 그것은 나타나지 않을 것입니다. 내가 뭐 놓친 거 없니?
답변1
배쉬 3을 사용하는 경우
대답은 사용 중인 bash 버전에 따라 다릅니다. 예를 들어 내 Mac에는 macOS High Sierra가 기본적으로 설치되어 있습니다 GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
. 이 경우 아래와 같이 trap -p EXIT >&2
함수의 명령에 괄호를 추가하면 문제를 해결할 수 있습니다 .fun
#!/bin/bash
exithdl() {
echo "in exithdl subshell=$BASH_SUBSHELL" >&2
}
trap exithdl EXIT
fun() {
echo "in fun subshell=$BASH_SUBSHELL" >&2
(trap -p EXIT >&2) # <--- See Here
echo "returned from fun"
}
echo "subshell=$BASH_SUBSHELL" >&2
trap -p EXIT >&2
echo "$(fun)" >&2
echo "exiting" >&2
아래 표시된 결과 출력에는 더 이상 트랩이 fun
있는 기능이 표시되지 않습니다 .EXIT
subshell=0
trap -- 'exithdl' EXIT
in fun subshell=1
returned from fun
exiting
in exithdl subshell=0
이 방법은 다른 트랩의 하위 집합에도 적용됩니다. 예를 들어, 이 하위 집합에는 , 및 INT
트랩이 포함됩니다 QUIT
. 그러나 이 하위 집합에는 기타 문제가 포함되지 않습니다.TERM
CHLD
HUP
Bash 4 및 5를 사용하는 경우
VirtualBox에 Ubuntu 18과 19도 설치했습니다. 이러한 운영 체제는 기본적으로 각각 GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
및 를 사용합니다 GNU bash, version 5.0.11(1)-release (x86_64-pc-linux-gnu)
. 위의 변경 사항을 적용하여 스크립트를 실행하면 결과는 원래 출력과 동일합니다. 그러나 이러한 최신 버전의 bash의 경우 trap
아래와 같이 기능에서 명령 앞에 명령을 추가하면 문제를 해결할 수 있습니다 .trap -p EXIT >&2
fun
#!/bin/bash
exithdl() {
echo "in exithdl subshell=$BASH_SUBSHELL" >&2
}
trap exithdl EXIT
fun() {
echo "in fun subshell=$BASH_SUBSHELL" >&2
trap -- KILL # <--- See Here
trap -p EXIT >&2
echo "returned from fun"
}
echo "subshell=$BASH_SUBSHELL" >&2
trap -p EXIT >&2
echo "$(fun)" >&2
echo "exiting" >&2
트랩을 변경할 수 없기 때문에 이 trap -- KILL
명령이 선택되었습니다 . KILL
그러면 위 이미지와 동일한 출력이 생성됩니다. 이 방법은 다른 트랩에도 적용됩니다.
결론적으로
exitTrap
현재 트랩을 정의하는 데 사용되는 명령에 대한 변수를 설정 하려면 (예를 들어) EXIT
아래 표시된 스크립트를 사용하십시오. 이것은 bash 3, 4 및 5에서 작동합니다.
trap -- KILL
exitTrap="$( (trap -p EXIT) )"