다음 스크립트를 시도했습니다.
#!/bin/bash
trap 'echo "touching a file" && touch $FILE' EXIT
foo1(){
echo "foo1"
}
foo(){
echo "foo"
export FILE=${FILE:-/tmp/file1}
}
(foo1)
foo
위 스크립트의 출력은 다음과 같습니다.
[root@usr1 my_tests]# ./test.sh
foo1
foo
touching a file
foo1
그러나 나는 트랩이 서브쉘에서 호출되는 출구에서도 호출될 것이라고 예상했습니다 .
- 이것이 예상되는가?
trap
서브쉘에 상속 되나요 ?- 그렇다면 어떤 상황에서
trap
서브쉘에 상속됩니까?
답변1
트랩 핸들러는 서브쉘에 의해 상속되지 않습니다. 이것은POSIX에 의해 지정됨:
무시되지 않는 트랩은 서브쉘에 들어갈 때 기본 동작으로 설정됩니다.
무시된 신호( trap '' SIGFOO
)는 서브쉘(및 쉘에 의해 시작된 외부 프로그램)에서 여전히 무시됩니다.
답변2
trap
하위 쉘에 전파되지는 않지만 일부 방법에서는 하위 쉘이 상위 쉘에 트랩을 보고하도록 허용하고 다른 방법에서는 그렇지 않습니다. bash를 사용하여 macOS에서 몇 가지 테스트를 수행했습니다.
GNU bash, 버전 4.4.12(1)-릴리스(x86_64-apple-darwin16.3.0):
trap 'echo hello' EXIT
trap # trap -- 'echo hello' EXIT
echo "$(trap)" # trap -- 'echo hello' EXIT
trap | cat # trap -- 'echo hello' EXIT
(trap) | cat # trap -- 'echo hello' EXIT
cat < <(trap) # empty
cat <<< "$(trap)" # empty
bash -c 'trap' # empty
trap & # trap -- 'echo hello' EXIT
GNU bash, 버전 3.2.57(1)-릴리스(x86_64-apple-darwin16):
trap 'echo hello' EXIT
trap # trap -- 'echo hello' EXIT
echo "$(trap)" # trap -- 'echo hello' EXIT
trap > >(cat) # trap -- 'echo hello' EXIT
trap | cat # empty
(trap) | cat # empty
cat < <(trap) # empty
cat <<< "$(trap)" # empty
bash -c 'trap' # empty
trap & # empty
trap_output="$(trap)"
이것이 트랩 출력에 도움이 될 것이라는 점을 알아두면 좋습니다 . 이것이 작동하지 않으면 trap >trap_output_file
파일로 출력한 다음(fifo는 작동하지 않음 bash 3.2.57
) 다시 읽는 것 외에는 다른 방법을 생각할 수 없습니다.trap_output="$(<trap_output_file)"
fifo 는 비어 있기 bash 3.2.57
때문에 작동하지 않지만 그렇지 않습니다.trap &
bash 3.2.57
bash 4.4.12
GNU bash, 버전 4.4.12(1)-릴리스(x86_64-apple-darwin16.3.0):
mkfifo /tmp/fifo; trap >/tmp/fifo & trap_output=$(</tmp/fifo); rm -f /tmp/fifo; echo "$trap_output"
# trap -- 'echo hello' EXIT
mkfifo /tmp/fifo; trap_output=$(</tmp/fifo) & trap >/tmp/fifo; rm -f /tmp/fifo; echo "$trap_output"
# empty because trap_output=$(</tmp/fifo) sets the variable in a subshell
GNU bash, 버전 3.2.57(1)-릴리스(x86_64-apple-darwin16):
mkfifo /tmp/fifo; trap >/tmp/fifo & trap_output=$(</tmp/fifo); rm -f /tmp/fifo; echo "$trap_output"
# empty because trap >/tmp/fifo & is empty since it uses trap &
mkfifo /tmp/fifo; trap_output=$(</tmp/fifo) & trap >/tmp/fifo; rm -f /tmp/fifo; echo "$trap_output"
# empty because trap_output=$(</tmp/fifo) sets the variable in a subshell
답변3
trap
정의는 서브쉘로 전파되지 않습니다.
식별 방법:
trap "echo bla" 1 2 3
(trap)
답변4
서브쉘을 호출 하면 trap
상위 트랩이 표시되지만 서브쉘에서는 실행되지 않습니다. 서브쉘에 새로운 트랩을 설정할 수 있습니다.
이를 테스트하려면 다음 코드를 사용하여 스크립트를 생성하고 실행한 후 ctrl+를 실행하세요 c.
#!/usr/bin/bash
function sub { echo sub_before: `trap`; trap 'echo kill_sub; exit' SIGINT; echo sub_after: `trap`; while :; do sleep 1; done; }
function parent { echo parent_before: `trap`; trap 'pkill -2 -P $$; echo kill_parent; exit' SIGINT; echo parent_after: `trap`; sub & wait; }
parent
두 트랩이 모두 실행되는 것을 볼 수 있습니다.
(배쉬 5.0.17)