2

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

Bash(或其他 shell):用函数/脚本包装所有命令

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

如何保留 readline 所做的好事,但仍能正确处理 SIGINT?理想情况下,它会将 continue 语句发送到 while read 循环,或者以某种方式将 \n 发送到我的读取正在等待的 STDIN。

示例代码:

#!/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
4

2 回答 2

0

我想我终于想出了一些我喜欢的东西。请参阅SIGINT 以取消在 bash 脚本中读取?对于那个答案。

于 2020-09-02T21:39:12.563 回答
-1

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

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

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

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

您将输出为

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

于 2016-11-19T08:54:49.000 回答