假设您有一个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
子外壳中运行...并且子外壳似乎没有继承trap
父对象的行为,这意味着如果您在此处执行任何应由陷阱代码清除的操作,则不会不会发生。
所以你试试这个:
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
陷阱