理论上,如果我知道正在运行的 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
您会注意到1
,2
和3
都是指向同一 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;