有人可以解释为什么会发生这种情况以及如何修复它,以便发送到 stdin 的数据的行为方式与输入到 stdin 的数据相同。
对于那些看不到 .gif 的人
基本上我有 3 个终端设置。一种是运行 netcat 服务器,其命令如下。
nc -l 127.0.0.1 4000
终端 2 仅运行 netcat 客户端,其命令如下。
nc 127.0.0.1 4000
当输入到客户端时,这基本上意味着将数据输入到该程序的 stdin 或文件描述符 0。一旦按下回车键,数据就会显示在服务器上。这是预期的行为。
人们会期望,如果您从键盘以外的其他来源向标准输入输入数据,只要您在末尾提供换行符,甚至换行符和回车符,它就会工作得一样。
但运行具有以下命令的终端 3 时情况并非如此。
echo "test\n" > /proc/$pid/fd/0
奇怪的是,来自 echo 的数据甚至出现在终端 2 中,但它不会被视为键盘输入,因此没有消息从终端 2 上的 clinet 发送到终端 1 上的服务器。
我的结论是胡说八道。
答案1
如果您查看该/proc/$PID/fd/0
链接,您会看到它指向终端:
# ls -l /proc/11962/fd/0
lrwx------ 1 foo users 64 Aug 15 04:30 /proc/11962/fd/0 -> /dev/pts/15
当您输出到它时,您不是将输入传递给进程nc
,而是输出到终端。它会正确打印您输出的内容。
它看起来像这样:
/proc/$PID/fd/$N <-------> [ ]
[ terminal ]
[ nc ] <--------------------> [ ]
不是这样的:
/proc/$PID/fd/$N
| |
[ ] <-----+ +------> [ ]
[ nc ] <--------------------> [ terminal ]
如果进程的文件描述符 0 被打开到一个文件,您是否仍然期望写入/proc/$PID/fd/0
显示为进程的输入,或者转到打开的文件?
lrwx------ 1 foo users 64 Aug 15 04:36 /proc/11994/fd/0 -> /tmp/testfile
echo foo > /proc/11994/fd/0
这种情况应该怎么办?
这里也是一样。当进程从fd读取数据时,它就从文件中读取数据。但是当您重新打开同一个文件进行写入时/proc/$PID/fd/$N
,您会写入到文件。
您需要使用 TIOCSTI ioctl 或某种类似的机制将数据填充到终端的输入缓冲区中。看tty_ioctl(4)