Bash脚本在读取循环时不捕获SIGINT

当我按Ctrl C时,我有几个脚本while read line循环时不会执行我的清理功能。例如:

#!/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设置仍然有效,我的终端被搞砸了。 我有许多其他脚本,我的清理功能完美无瑕。 我似乎遇到问题的唯一时间是在脚本处于read循环时按Ctrl-C。 有没有办法确保当脚本在read循环中时按下Ctrl-C时cleanup函数会被调用? 或者我在这里错过了一些明显的东西?

更新:我的脚本中还有其他内容正在发生。 我运行了上面的确切脚本,并且我无法让它以我其他脚本的方式失败。 我将不得不尝试将破损的脚本提炼出来,以便我可以失败,此时我会更新问题。

更新2:好的,我明白了。 我从stty中得到一个错误(我没有看到,因为我的真正清理功能也清除了屏幕)。 错误是: stty: standard input: Inappropriate ioctl for device 。 我查看了一下,显然这是由于在stdin从文件/foo/bar重定向时调用stty 。 所以我改变了我的trap调用trap "break" SIGINT SIGHUP SIGTERM ,它的工作。


事实证明,问题是由于我的cleanup函数调用了sttystty显然不喜欢在stdin从文件重定向时调用。 因此,当我在脚本执行read循环时按Ctrl-C时, cleanup函数被调用,就好像我已经从循环中调用它:

while read -r line; do
  ...
  cleanup
  ...
done < "$filename"

这反过来又意味着stty被重定向的stdin执行,并且它以错误stty: standard input: Inappropriate ioctl for device而死stty: standard input: Inappropriate ioctl for device

我可以通过改变我的trap线来解决这个问题:

trap "break" SIGINT SIGHUP SIGTERM

因此,当我按下Ctrl-C时,它不是有效地将一个调用cleanup插入到我的循环中,而是只是(有效地)在循环中插入一个break ,从而打破循环并随后通过行后调用cleanup函数循环。

链接地址: http://www.djcxy.com/p/78407.html

上一篇: Bash script doesn't catch SIGINT while in read loop

下一篇: Blurry text on Chrome when using CSS