假设您有一个 shell 脚本,它通过EXIT
陷阱运行某种清理代码,如下所示:
#!/bin/bash
mytrap () {
echo "It's a trap!" >&2
}
trap mytrap exit
echo I am at the end of the script.
正如预期的,这将It's a trap!
在脚本退出时打印出来:
$ sh myscript
I am at the end of the script.
It's a trap!
您修改脚本以添加一个函数,该函数生成一些输出,最终通过管道传输到另一个命令,如下所示:
#!/bin/bash
mytrap () {
echo "It's a trap!" >&2
}
myfunc () {
echo "I've got a bad feeling about this..."
}
trap mytrap exit
myfunc | cat > /dev/null
echo I am at the end of the script.
由于管道的原因,其中的代码myfunc
在子 shell 中运行...并且子 shell 似乎不会继承trap
父 shell 的行为,这意味着如果您在此处执行任何应该由陷阱代码清除的操作,则不会'不会发生。
所以你尝试这样做:
myfunc () {
trap mytrap EXIT
echo "I've got a bad feeling about this..."
}
mytrap
并且当子shell退出时仍然无法触发。事实证明,您需要一个显式的exit
,如下所示:
myfunc () {
trap mytrap EXIT
echo "I've got a bad feeling about this..."
exit
}
使用上面的代码,mytrap
将在退出子 shell 时适当触发:
$ sh myscript
It's a trap!
I am at the end of the script.
It's a trap!
这是预期的行为吗?我对这里的几件事感到惊讶:
trap
设置不被子 shell 继承- 从子 shell 隐式退出似乎不会触发
EXIT
陷阱