【问题标题】:How to handle interrupt signal when reading from stdin in bash [duplicate]从bash中的stdin读取时如何处理中断信号[重复]
【发布时间】:2016-11-19 01:27:01
【问题描述】:

我在玩 bash 读取功能。我喜欢我目前外壳上的一个简单层。 read -e 执行制表符完成和以前的命令,并使用 ctrl+d 发送 EOF 让我回到原来的 shell。这是我的参考:

Bash (or other shell): wrap all commands with function/script

我想要一些处理 SIGINT 的帮助,ctrl+c。在普通的 shell 中,如果您开始键入并在中途按 ^C,它会立即结束该行。对于这个简单的示例,在 ^C 之后,我仍然必须在注册之前按回车键。

我如何保留 readline 的优点,但仍能正确处理 SIGINT?理想情况下,它会向 while 读取循环发送一条 continue 语句,或者以某种方式向我的读取正在等待的 STDIN 发送一个 \n。

示例代码:

#!/bin/bash
# Emulate bash shell

gtg=1

function handleCtrl-C {
    # What do I do here?
    gtg=0
    return
}

trap handleCtrl-C INT

while read -e -p "> " line
do
    if [[ $gtg == 1 ]] ; then
        eval "$line"
    fi
    gtg=1
done

【问题讨论】:

    标签: bash readline interactive sigint bash-trap


    【解决方案1】:

    我想我终于想出了一些我喜欢的东西。有关该答案,请参见 SIGINT to cancel read in bash script?

    【讨论】:

      【解决方案2】:

      阅读 man 7 信号表明某些系统调用设置了可重新启动标志,结果将返回到命令

      对于某些系统调用,如果在调用过程中捕获到信号 执行和调用被提前终止,调用是 自动重启。任何使用 signal(3) 安装的处理程序都会 设置了 SA_RESTART 标志,这意味着任何可重新启动的系统调用 收到信号后不会返回。受影响的系统调用 包括 read(2)、write(2)、sendto(2)、recvfrom(2)、sendmsg(2) 和 recvmsg(2) 在通信通道或低速设备上,并且 在 ioctl(2) 或 wait(2) 期间。但是,已经调用 提交的不会重新启动,而是返回部分成功(对于 例如,短读计数)。这些语义可以改变 信号中断(3)。

      您可以尝试将输入的值打印到 line 并验证在 CtrlC 返回后恢复读取,直到点击新行。输入“exit”之类的内容,然后按 Ctrl-C,然后“exit”输出为“exitexit”。进行以下更改并运行上述测试用例

      echo ">$line<"
      if [ $gtg == 1 ] ; then
      

      你将输出为

      您也可以使用 C 程序验证这一点。

      【讨论】:

      • 我不确定这是否是我想要的 - 如果我输入“退出”并按 Ctrl-C,我希望它放弃退出并给我一个新的提示。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-05
      • 1970-01-01
      • 2011-04-07
      • 2019-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多