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

当我按下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时,它不是有效地将清理调用插入到循环中,而是仅仅(有效地)将一个中断插入到循环中,从而突破循环并随后通过该行调用清理函数循环.

相关文章

普通模式 >G 增加当前行到文档末尾处的缩紧层级 $ 移动到本行的末尾 . 相当于一个...
原文连接: https://spacevim.org/cn/layers/lang/elixir/ 模块简介 功能特性 启用模块 快捷键 语言专属...
原文连接: https://spacevim.org/cn/layers/lang/dart/ 模块简介 功能特性 依赖安装及启用模块 启用模...
 =   赋值操作符,可以用于算术和字符串赋值 +        加法计算     -        减法运算...
1.根据包名来查看指定的APP指定数据 adb shell "top | grep com.xxx.xxx" 由于这样打印出来的数...
ctrl+F 向下翻页 ctrl+B 向下翻页 u 取消最近一次操作 U 取消当前行的操作 ZZ 保存当前内容并退出 gg 跳...