理论上,如果我知道正在运行的 bash shell 的 pid,我可以运行一个 cat,它的 stdout 被重定向到该 shell 的 stdin。好像我在那个 shell 上输入了一些东西。不幸的是,将会有来自 cat 的流,但不会使 shell 正常运行(来自 cat 的输入命令不会被 bash 执行)。
打开终端:
ps -ef | grep bash
ymf 4906 4887 0 16:19 pts/0 00:00:00 /bin/bash
Run Code Online (Sandbox Code Playgroud)
在另一个终端上:
cat 1> /proc/4906/fd/0
echo 'hello!'
Run Code Online (Sandbox Code Playgroud)
为什么?
我厌倦了评论中的“仅一段”限制=)
如果您启动 shellsh并获取 pid,$pid您可以按照您的描述找到文件描述符。一个例子:
$ ls -l /proc/29201/fd
total 0
lrwx------ 1 eroen users 64 Mar 22 15:52 0 -> /dev/pts/2
lrwx------ 1 eroen users 64 Mar 22 15:52 1 -> /dev/pts/2
lrwx------ 1 eroen users 64 Mar 22 15:52 2 -> /dev/pts/2
lrwx------ 1 eroen users 64 Mar 22 15:52 255 -> /dev/pts/2
Run Code Online (Sandbox Code Playgroud)
您会注意到1,2和3都是指向同一个 tty(chardev)的符号链接。换句话说,进程的输入是从写入输出的同一设备节点读取的。
当您尝试(在不同的进程中)写入相同的 tty(作为/proc/$pid/fd/0或者/dev/pts/?您完成与进程本身在将数据写入其输出时所做的完全相同的事情)时;数据显示在终端窗口中。
实际上,在启动进程后更改 fd[0-2] 指向的位置相当复杂,但并非不可能。Reptyr是一个免费的开源应用程序,它修改现有进程,因此它的 fd[0-2] 指向不同的 tty(以及其他一些东西)。这是通过ptrace框架完成的。这篇文章还提到了其他做同样事情的软件,并且可以通过gdb来完成。
根据您实际想要完成的任务,您可能会发现 Repty 或其他一些软件可以满足您的需求。否则,您可以查看/复制/修改源代码并了解它们是如何实现的。
转到终端 A 任何类型 tty
你会得到类似“/dev/pts/0”的东西
现在,转到终端 B 并输入exec 0</dev/pts/0(或 tty 命令给您的任何内容)
返回终端 A,您输入的命令将在终端 B 上运行。