트랩은 서브 쉘에 상속됩니까?


14

다음 스크립트를 시도했습니다.

#!/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에 서브 쉘 이 상속합니까?

답변:


10

트랩 핸들러는 서브 쉘에 의해 상속되지 않습니다. 이것은 POSIX에 의해 지정됩니다 .

서브 쉘을 입력하면 무시되지 않는 트랩이 기본 조치로 설정됩니다.

무시 된 신호 ( trap '' SIGFOO)는 하위 셸 (및 셸에서 시작한 외부 프로그램)에서도 무시됩니다.


3
bash에서는 set -E서브 쉘이 트랩을 상속 받도록 할 수 있지만 (적어도 내 경험으로는) 제대로 이해하는 것은 까다 롭습니다.
dragon788

이것이 모든 함정에 효과가 있는지 모르겠습니다. 나는 그것이 ERR에 대해 작동한다는 것을 알고 있습니다
yosefrow

4

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파일로 출력 하고 (오 작은 작동하지 않음) 파일 bash 3.2.57을 다시 읽는 것 외에 작동하지 않으면 다른 방법을 생각할 수 없습니다.trap_output="$(<trap_output_file)"

비어 bash 3.2.57있기 때문에 fifo가 작동 하지 않습니다.trap &bash 3.2.57bash 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

2

trap 정의는 하위 셸로 전파되지 않습니다.

확인 방법 :

trap "echo bla" 1 2 3"

(trap)


2
많은 쉘 (trap)이 특수한 경우로 처리 되므로 서브 쉘이 상위 쉘의 트랩을보고 할 수 있지만 실제로는 사용할 수는 없습니다. 따라서 테스트가 항상 신뢰할 수있는 것은 아닙니다.
JigglyNaga 10

Bourne Shell과 함께 작동하며 ksh88, bosh(schily Bourne Shell) 및 heirloom-sh. 당신은 맞습니다 : ksh93다르게 행동합니다.
schily

문제의 스크립트가 사용하는 bash에서는 작동하지 않습니다.
JigglyNaga

글쎄, 그것은 bash에서 작동합니다 : bash호출하면 아무것도 출력하지 않습니다 (trap).
schily
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.