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

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

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

在另一个终端上:

cat 1> /proc/4906/fd/0
echo 'hello!'

为什么?

答案1

我厌倦了评论中的“只能一个段落”的限制=)

如果你启动一个 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

您会注意到123都是指向同一 tty(chardev)的符号链接。换句话说,进程的输入是从与输出写入相同的设备节点读取的。

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

实际上,在启动一个进程后改变 fd[0-2] 指向的位置相当复杂,但并非不可能。雷普特尔是一个免费的开源应用程序,它修改现有进程,使其 fd[0-2] 指向不同的 tty(以及一些其他内容)。这是通过跟踪框架。该帖子还提到了其他可以做同样事情的软件,并且可以通过数据库

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

附录:
包含一些说明图,特别是第三从顶部看的示意图。

答案2

前往航站楼 A 任意类型tty

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

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

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

答案3

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

使用 C (https://stackoverflow.com/a/7370822.我还没有测试过):

char* cmd="ls\n";
int fd = open (ptsname, O_RDWR);

while (*cmd)
{
    ioctl(fd, TIOCSTI, cmd++);
}

使用 Perl (https://unix.stackexchange.com/a/48221. 完美运行,但仅适用于当前 shell):

require "sys/ioctl.ph";
ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV;

相关内容