我尝试使用以下脚本来模拟您观察到的内容(在 Mac OS X 10.8.4 上):
父脚本.sh
SCRIPT=./another-script.sh
trap "echo Exiting; exit 1" 0 1 2 3 13 15
eval $SCRIPT
trap 0
echo "Normal exit"
另一个脚本.sh
for i in $(seq 1 100)
do echo "Sequence $i"; sleep 2; done
当我运行它时,我得到了,例如:
$ ./parent-script.sh
Sequence 1
Sequence 2
Sequence 3
Sequence 4
^CExiting
Exiting
$
当我another-script.sh
这样修改时:
trap '' 1 2 3 13 15
for i in $(seq 1 100)
do echo "Sequence $i"; sleep 2; done
我得到了(异常?)行为:
$ ./parent-script.sh
Sequence 1
Sequence 2
Sequence 3
Sequence 4
^CSequence 5
Sequence 6
^CSequence 7
^CSequence 8
Sequence 9
^CSequence 10
^CSequence 11
^\Sequence 12
Sequence 13
Sequence 14
Sequence 15
Sequence 16
Sequence 17
Sequence 18
Sequence 19
Sequence 20
./parent-script.sh: line 3: 71135 Abort trap: 6 ./another-script.sh
Exiting
Exiting
$
我不得不创建另一个终端窗口并发送kill -6 71135
以停止父进程,我认为这是完全错误的。我向父进程发送了中断;当我这样做时,它应该立即退出(通过陷阱)。它应该让子进程运行;它使自己免受中断。我以前对这种行为感到愤怒。eval
不需要得到效果;没有它执行脚本就足够了。
但是,ksh
也表现出相同的方式。因此,要么 Apple 一直小心地将相同的错误引入到两个 shell 中,要么就是某人(POSIX?)规定 shell 应该表现的方式。