PSk*_*cik 9 bash ksh dash trap
这是一个简单的脚本,它在当前目录中设置一个临时目录,并在退出时设置一个陷阱以将其删除。
#filename: script
set -x
trap 'rm -rf "$d"' exit
d=`TMPDIR=$PWD mktemp -d`
"$@"
Run Code Online (Sandbox Code Playgroud)
如果我执行ksh script sleep 100或bash script sleep 100中断它C-C,则执行陷阱并删除目录。它不适用于dash. 为什么?这是错误还是预期行为?
Sté*_*las 19
zsh, pdksh(虽然不是mksh从它派生的最新版本),yashBourne shell 的行为类似于dash.
只有bash、ksh88、ksh93和mksh其他行为。
POSIX 规范并不清楚什么应该是正确的行为,但其中没有任何内容表明允许 shell 覆盖SIGINT(或其他)信号的默认处理程序。
它说EXIT应该在exit调用时评估陷阱动作,但是 AFAICT,它甚至没有说,例如,是否应该在 shell 退出时评估它,因为set -e或set -u或错误条件(如语法错误或特殊内置失败)。
为了能够EXIT在接收到信号时运行陷阱,shell 需要在该信号上安装一个处理程序。
这就是ksh,mksh和bashdo ,但是它们处理的信号列表在所有三个实现之间是不同的。所有 3 种之间唯一共有的信号似乎是INT, QUIT, TERM,ALRM和HUP。
如果您希望EXIT陷阱在某些信号上运行,可移植的方法是自己处理这些信号:
trap 'exit 1' INT HUP QUIT TERM ALRM USR1
trap 'cleanup' EXIT
Run Code Online (Sandbox Code Playgroud)
然而,这种方法不适用于zsh,EXIT如果exit从陷阱处理程序调用它不会运行陷阱。
它也没有向您的父母报告您的死亡信号。
因此,您可以这样做:
for sig in INT QUIT HUP TERM ALRM USR1; do
trap "
cleanup
trap - $sig EXIT
kill -s $sig "'"$$"' "$sig"
done
trap cleanup EXIT
Run Code Online (Sandbox Code Playgroud)
现在,请注意,如果在您执行时有更多信号到达cleanup,则cleanup可能会再次运行。cleanup如果多次调用和/或在执行期间忽略信号,您可能希望确保您的工作正常。
| 归档时间: |
|
| 查看次数: |
4789 次 |
| 最近记录: |