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 代表第一个后台命令?
是的,但你需要多一点。
当您将程序发送到后台时,您将其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
变成被转移到stdin
for command_that_expects_input
。
一旦你开始:
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,并在同一管道上重新打开它。