管道命令输出到运行/背景命令的输入

Gre*_*hal 4 bash io-redirection job-control

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

command that expects input &
echo some output | %1
Run Code Online (Sandbox Code Playgroud)

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

bah*_*mat 5

是的,但你需要多一点。

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

$ mkfifo alternate_input
$ command_that_expects_input < alternate_input
Run Code Online (Sandbox Code Playgroud)

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

$ echo foo > alternate_input
Run Code Online (Sandbox Code Playgroud)

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


Sté*_*las 3

一旦你开始:

rm -i -- * &
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

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

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