在 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
将被转移到stdin
for 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 所说,如果您知道首先需要管道输入,那就容易多了。在极少数(我从未遇到过)程序现在不需要输入但将来需要输入的情况下,您可以设置一个命名管道作为该进程的输入,将其置于后台,然后发送稍后启动的进程到同一个命名管道,但您必须事先设置命名管道。