TTY 控制字符发送到 sh 的标准输入不起作用

TTY 控制字符发送到 sh 的标准输入不起作用

我尝试开发一个可以启动的远程应用程序并在那里重新发送传入的数据,发现某些特殊序列不起作用。

因此,出于测试目的,我在桌面上启动sh,然后执行一个命令,接下来尝试通过从另一个 shellping localhost执行来中断 ping 。echo -e "\003" > /proc/$shPID/fd/0字节是+组合0x3产生的字节。无论我尝试什么CtrlC(添加换行符,在开头添加CSI),它不起作用——字符只是出现在标准输出中 (我的意思是例如换行符),但不会中断 ping 运行。

如何通过 sh 的 stdin 中断 ping?

答案1

^C 处理是由终端设备驱动程序完成的,而不是 shell。

当在连接到 tty 设备的线路上接收到该字符时(或者在伪终端对的主端的主端上写入该字符(就像xterm按 时所做的那样Ctrl+C)),tty 线路规则( kernel)向终端的前台进程组发送SIGINT信号。

因此,您需要将该字符发送到 xterm 在主控端打开的 fd 上。

$ eval "$(xprop -notype -id $WINDOWID 32i '=$0\n' _NET_WM_PID)"; lsof -ap "$_NET_WM_PID" /dev/ptmx
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
xterm   21123 stephane    4u   CHR    5,2      0t0 1460 /dev/ptmx

在 Linux 上写入它/proc/21123/fd/4是行不通的,因为这只会重新打开,/dev/ptmx因此不会引用相同的伪终端。你需要说服 xterm将 ^C 写入其 fd 4。

所以这并不是一个真正的选择。

您可以启动自己的伪终端对并在其中运行 sh 和 ping`。然后,您可以在主端写入 ^C 以便将该 SIGINT 发送到前台进程组,但这里更简单的是直接发送信号(首选 SIGTERM)。

另请注意,尝试在 , 上写入字符/proc/$pid/fd/0并没有真正意义。文件描述符通常打开以供读取。在 Linux 上,执行 open() 实际上/proc/$pid/fd/0会重新打开该 fd 指向的资源。

因此,例如,如果shwas 开始于sh < /some/file,执行操作将替换withecho something > "/proc/$shpid/fd/0"的内容。如果它是一个 tty,那么它只会显示在该终端上。写入会读取某些内容的唯一情况是当 sh stding 是管道时。在 Linux(且仅限 Linux)上,如果您执行写入模式(其中是管道),则会打开该管道的写入端(而 fd 0 实际上指向读取端)。/some/filesomething\nsomethingsomethingshopen()/proc/$shpid/fd/0

相关内容