如何读取 Ctrl+C 作为输入
How to read Ctrl+C as input
(在Linux)
我找到的方法都是用signal
.
没有别的办法了吗?有什么办法可以让终端将它放入输入缓冲区吗?
为了“读取 CTL+C 作为输入”而不是让它生成 SIGINT
,有必要 to use tcsetattr
() 清除 cc_c[VINTR]
或清除 ISIG
标志,如我在此处链接到的手册页中所述。
您将需要使用 tcgetattr
,首先,读取当前终端设置,相应地进行调整,然后 tcsetattr
进行设置。
您应该确保终端设置在您的程序终止时重置为原始默认值,shell 不一定会为您重置为默认值。
不,signal()
不是这样。您应该需要配置 tty
驱动程序来执行 原始输入 (驱动程序中没有输入字符处理),因此它会原封不动地传递所有字符。但这需要将 tty
输入设备视为特殊设备并编写特殊代码来处理这种情况(这需要您发出多个 ioctl
系统调用)。但不推荐这样做,原因如下所述。
其次,还有另一种更简单的方法,不需要使用原始模式。您可以通过在 tty
转义字符前添加 转义 Ctrl-C 字符。 在 Linux 和 BSD 系统中,这通常与 Ctrl-V 字符相关联,因此按 Ctrl-V + Ctrl-C 允许您输入单个 Ctrl-C 字符。我刚刚用 hd
命令检查了它:
$ hd
^C
00000000 : 03 0a : ..
00000002
$ _
接下来的问题是,那么,如何输入Ctrl-V呢?好吧,加倍! (但我们现在超出范围,请继续阅读)
这种方法的优点是它不需要在您的程序中编程,并且在从文件、管道、fifo、套接字等读取时将以相同的方式工作(Ctrl-C 对此没有特殊要求)意思是,因为 tty
驱动程序不在现场)检测到 Ctrl-C 时唯一产生中断的设备是 tty
驱动程序(更确切地说,控制 tty
,在它的代码中通用部分,所以所有 tty
s 都这样做)并且它还有一个转义字符(出于同样的原因,所有 tty
s 都有它)使下一个字符的特殊含义无效。
可以用stty(1)
命令查看哪个字符是转义字符,配置为lnext
条目。但我几乎可以向你保证它会是 Ctrl-V。
备注
这也适用于终端用于特殊用途的任何其他特殊字符(如 Ctrl-D、Ctrl-H 等)
(在Linux)
我找到的方法都是用signal
.
没有别的办法了吗?有什么办法可以让终端将它放入输入缓冲区吗?
为了“读取 CTL+C 作为输入”而不是让它生成 SIGINT
,有必要 to use tcsetattr
() 清除 cc_c[VINTR]
或清除 ISIG
标志,如我在此处链接到的手册页中所述。
您将需要使用 tcgetattr
,首先,读取当前终端设置,相应地进行调整,然后 tcsetattr
进行设置。
您应该确保终端设置在您的程序终止时重置为原始默认值,shell 不一定会为您重置为默认值。
不,signal()
不是这样。您应该需要配置 tty
驱动程序来执行 原始输入 (驱动程序中没有输入字符处理),因此它会原封不动地传递所有字符。但这需要将 tty
输入设备视为特殊设备并编写特殊代码来处理这种情况(这需要您发出多个 ioctl
系统调用)。但不推荐这样做,原因如下所述。
其次,还有另一种更简单的方法,不需要使用原始模式。您可以通过在 tty
转义字符前添加 转义 Ctrl-C 字符。 在 Linux 和 BSD 系统中,这通常与 Ctrl-V 字符相关联,因此按 Ctrl-V + Ctrl-C 允许您输入单个 Ctrl-C 字符。我刚刚用 hd
命令检查了它:
$ hd
^C
00000000 : 03 0a : ..
00000002
$ _
接下来的问题是,那么,如何输入Ctrl-V呢?好吧,加倍! (但我们现在超出范围,请继续阅读)
这种方法的优点是它不需要在您的程序中编程,并且在从文件、管道、fifo、套接字等读取时将以相同的方式工作(Ctrl-C 对此没有特殊要求)意思是,因为 tty
驱动程序不在现场)检测到 Ctrl-C 时唯一产生中断的设备是 tty
驱动程序(更确切地说,控制 tty
,在它的代码中通用部分,所以所有 tty
s 都这样做)并且它还有一个转义字符(出于同样的原因,所有 tty
s 都有它)使下一个字符的特殊含义无效。
可以用stty(1)
命令查看哪个字符是转义字符,配置为lnext
条目。但我几乎可以向你保证它会是 Ctrl-V。
备注
这也适用于终端用于特殊用途的任何其他特殊字符(如 Ctrl-D、Ctrl-H 等)