将命令输出连接到正在运行/后台命令的输入

将命令输出连接到正在运行/后台命令的输入

在 Bash 4.X 中,可以执行以下操作:

command that expects input &
echo some output | %1

其中 %1 代表第一个后台命令?

答案1

是的,但你还需要多一点。

当您将程序发送到后台时,您将其stdin与终端的关联分离。您需要使用备用输入(在本例中为管道)来启动它。

$ mkfifo alternate_input
$ command_that_expects_input < alternate_input

您现在已将管道文件 ( alternate_input) 指定为stdin进程的文件command_that_expects_input。要发送输入,只需将一些东西放入管道中即可。

$ echo foo > alternate_input

在这种情况下,字符串foo将被转移到stdinfor command_that_expects_input

答案2

一旦你开始:

rm -i -- * &

rm已使用调用该命令时 shell 中的任何 stdin 启动。

如果它是终端,那么rm一旦尝试从中读取(因为它不在终端的前台进程组中),通常就会被挂起(使用 SIGTTIN 信号)。

如果你希望它从其他东西读取,你必须告诉它在其他东西上重新打开其文件描述符 0。

您可以使用调试器来做到这一点(这里假设您使用的是 Linux):

rm_pid=$!
coproc yes
gdb --pid="$rm_pid" --batch \
    -ex "call close(0)" \
    -ex "call open(\"/proc/$$/fd/$COPROC\", 0)" /bin/rm
kill -s CONT "$rm_pid"

上面,我们yes从后台开始,将其标准输入和标准输出重定向到管道。该管道的另一端位于$$文件描述符${COPROC[0]}(又名)上的 shell(进程)中$COPROC

然后,使用gdb,我们告诉rm关闭其 fd 0,并在同一管道上重新打开它。

答案3

按照你的假设,不。正如 terdon 所说,如果您知道首先需要管道输入,那就容易多了。在极少数(我从未遇到过)程序现在不需要输入但将来需要输入的情况下,您可以设置一个命名管道作为该进程的输入,将其置于后台,然后发送稍后启动的进程到同一个命名管道,但您必须事先设置命名管道。

相关内容