我尝试开发一个可以启动的远程应用程序嘘并在那里重新发送传入的数据,发现某些特殊序列不起作用。
因此,出于测试目的,我在桌面上启动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 指向的资源。
因此,例如,如果sh
was 开始于sh < /some/file
,执行操作将替换withecho something > "/proc/$shpid/fd/0"
的内容。如果它是一个 tty,那么它只会显示在该终端上。写入会读取某些内容的唯一情况是当 sh stding 是管道时。在 Linux(且仅限 Linux)上,如果您执行写入模式(其中是管道),则会打开该管道的写入端(而 fd 0 实际上指向读取端)。/some/file
something\n
something
something
sh
open()
/proc/$shpid/fd/0