从 bash 中的标准输入读取时如何处理中断信号
How to handle interrupt signal when reading from stdin in bash
我正在尝试 bash 读取功能。到目前为止,我喜欢在当前 shell 之上的一个简单层。 read -e 执行 tab-complete 和之前的命令,使用 ctrl+d 发送 EOF 让我回到原来的 shell。这是我的参考:
Bash (or other shell): wrap all commands with function/script
我需要一些处理 SIGINT 的帮助,ctrl+c。在正常的 shell 中,如果您开始键入并半按 ^C,它会立即结束该行。对于这个简单的示例,在 ^C 之后,我仍然必须在注册之前点击 return。
如何保持 readline 的优点,但仍能正确处理 SIGINT?理想情况下,它会向 while read 循环发送一个 continue 语句,或者以某种方式将 \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
阅读 man 7 signal 表明某些系统调用设置了可重启标志,因此将 return 返回到命令
For some system calls, if a signal is caught while the call is
executing and the call is prematurely terminated, the call is
auto-matically restarted. Any handler installed with signal(3) will
have the SA_RESTART flag set, meaning that any restartable system call
will not return on receipt of a signal. The affected system calls
include read(2), write(2), sendto(2), recvfrom(2),sendmsg(2), and
recvmsg(2) on a communications channel or a low speed device and
during a ioctl(2) or wait(2). However, calls that have already
committed are not restarted, but instead return a partial success (for
example, a short read count). These semantics could be changed with
siginterrupt(3).
您可以尝试将输入的值打印到行并验证读取在 CtrlC return 后恢复,直到命中新行。输入类似 "exit" 的内容,然后按 Ctrl-C,然后输入 "exit",输出结果为 "exitexit"。对上述测试用例
进行以下更改和运行
echo ">$line<"
if [ $gtg == 1 ] ; then
您将输出为
您也可以使用 C 程序验证这一点。
我想我终于想出了一些我喜欢的东西。请参阅 SIGINT to cancel read in bash script? 以获得该答案。
我正在尝试 bash 读取功能。到目前为止,我喜欢在当前 shell 之上的一个简单层。 read -e 执行 tab-complete 和之前的命令,使用 ctrl+d 发送 EOF 让我回到原来的 shell。这是我的参考:
Bash (or other shell): wrap all commands with function/script
我需要一些处理 SIGINT 的帮助,ctrl+c。在正常的 shell 中,如果您开始键入并半按 ^C,它会立即结束该行。对于这个简单的示例,在 ^C 之后,我仍然必须在注册之前点击 return。
如何保持 readline 的优点,但仍能正确处理 SIGINT?理想情况下,它会向 while read 循环发送一个 continue 语句,或者以某种方式将 \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
阅读 man 7 signal 表明某些系统调用设置了可重启标志,因此将 return 返回到命令
For some system calls, if a signal is caught while the call is executing and the call is prematurely terminated, the call is auto-matically restarted. Any handler installed with signal(3) will have the SA_RESTART flag set, meaning that any restartable system call will not return on receipt of a signal. The affected system calls include read(2), write(2), sendto(2), recvfrom(2),sendmsg(2), and recvmsg(2) on a communications channel or a low speed device and during a ioctl(2) or wait(2). However, calls that have already committed are not restarted, but instead return a partial success (for example, a short read count). These semantics could be changed with siginterrupt(3).
您可以尝试将输入的值打印到行并验证读取在 CtrlC return 后恢复,直到命中新行。输入类似 "exit" 的内容,然后按 Ctrl-C,然后输入 "exit",输出结果为 "exitexit"。对上述测试用例
进行以下更改和运行echo ">$line<"
if [ $gtg == 1 ] ; then
您将输出为
您也可以使用 C 程序验证这一点。
我想我终于想出了一些我喜欢的东西。请参阅 SIGINT to cancel read in bash script? 以获得该答案。