当我按下Ctrl C时,我有几个脚本,而读取行循环不执行我的清理功能.例如:
#!/bin/bash cleanup() { stty echo exit 0 } trap cleanup SIGINT SIGHUP SIGTERM stty -echo while read -r line; do echo "$line" done < /foo/bar cleanup
当我按下Ctrl-C时,我的终端被搞砸了,因为stty -echo设置仍然有效.我有许多其他脚本,我的清理功能完美无缺.我遇到问题的唯一一次是在脚本处于读取循环时按Ctrl-C.当脚本在读取循环中时,有没有办法确保在按下Ctrl-C时调用清理函数?或者我只是错过了一些明显的东西?
更新:我的脚本中还有其他内容.我运行上面的确切脚本,我不能让它像我的其他脚本那样失败.我将不得不尝试将破碎的脚本提炼为我可以失败的东西,此时我将更新问题.
更新2:好的,我明白了.我从stty得到了一个错误(我没有看到,因为我的真正的清理功能也在清除屏幕).错误是:stty:标准输入:设备不适当的ioctl.我看了一下这显然是因为当stdin从文件/ foo / bar重定向时调用了stty.所以我改变了我的陷阱调用陷阱“中断”SIGINT SIGHUP SIGTERM并且它起作用了.
事实证明问题是由于我的清理函数正在调用stty,而stty显然不喜欢在从文件重定向stdin时调用它.因此,当我在脚本执行读取循环时按下Ctrl-C时,清理函数被调用,就像我在循环中调用它一样:
while read -r line; do ... cleanup ... done < "$filename"
反过来,这意味着stty是使用重定向的stdin执行的,并且它因错误stty而死:标准输入:设备的不适当的ioctl.
我能够通过改变我的陷阱线来解决这个问题:
trap "break" SIGINT SIGHUP SIGTERM
因此,当我按下Ctrl-C时,它不是有效地将清理调用插入到循环中,而是仅仅(有效地)将一个中断插入到循环中,从而突破循环并随后通过该行调用清理函数循环.