如何重定向到正在运行的 bash shell 的标准输入?

Det*_*ant 7 bash redirection

理论上,如果我知道正在运行的 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)

为什么?

Ero*_*oen 7

我厌倦了评论中的“仅一段”限制=)

如果您启动 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,23都是指向同一个 tty(chardev)的符号链接。换句话说,进程的输入是从写入输出的同一设备节点读取的。

当您尝试(在不同的进程中)写入相同的 tty(作为/proc/$pid/fd/0或者/dev/pts/?您完成与进程本身在将数据写入其输出时所做的完全相同的事情)时;数据显示在终端窗口中。

实际上,在启动进程后更改 fd[0-2] 指向的位置相当复杂,但并非不可能。Reptyr是一个免费的开源应用程序,它修改现有进程,因此它的 fd[0-2] 指向不同的 tty(以及其他一些东西)。这是通过ptrace框架完成的。这篇文章还提到了其他做同样事情的软件,并且可以通过gdb来完成。

根据您实际想要完成的任务,您可能会发现 Repty 或其他一些软件可以满足您的需求。否则,您可以查看/复制/修改源代码并了解它们是如何实现的。

附录:
包含一些说明图,特别是顶部的第三个原理图。

  • 更少的魔法和更多的“内核内部”,但是是的。 (2认同)

Jef*_*ffG 5

转到终端 A 任何类型 tty

你会得到类似“/dev/pts/0”的东西

现在,转到终端 B 并输入exec 0</dev/pts/0(或 tty 命令给您的任何内容)

返回终端 A,您输入的命令将在终端 B 上运行。

  • 让我提一下,这会创建一个 *有趣的* 竞争条件,这在我的系统上使得哪个 shell 获得一个字符似乎是随机的。 (3认同)