如何将 shell 脚本的标准输入传递给后台命令

如何将 shell 脚本的标准输入传递给后台命令

在 shell 脚本中,我尝试启动一个与 shell 脚本具有相同标准输入的后台命令。

#!/bin/sh
# ...

the-program &

但是,the-program上面的方法将无法访问与 shell 脚本相同的标准输入。根据我的外壳手册(破折号(1)):

如果 shell 不是交互式的,则异步命令的标准输入将设置为/dev/null

我尝试过the-program & <&0,但似乎没有达到预期的效果;的标准输入the-program仍然是/dev/null.

我考虑过通过复制 shell 脚本的标准输入来创建一个新的文件描述符,并以某种方式将该新的文件描述符传递给后台进程。但是,后台进程必须以某种方式将该新文件描述符重定向到其标准输入(替换/dev/null)。我不知道这个想法是否可行,我也不知道如何在 POSIX sh 中实现它。

答案1

是的,这很烦人POSIXsh规范的要求通过非交互式 shell 调用异步启动的命令(当monitor未启用 IOW 作业控制选项时)将其标准输入重定向到 /dev/null。

如果禁用作业控制(请参阅set-m),则在执行任何显式重定向之前,异步列表的标准输入应被视为分配给与 具有相同属性的文件/dev/null。如果启用作业控制,则不会发生这种情况。在所有情况下,标准输入的显式重定向应覆盖此活动。

通常的解决方法是:

{ cmd <&3 3<&- & } 3<&0

这听起来像你的想法。

例子:

$ sh -c 'readlink /proc/self/fd/0 & wait' < /
/dev/null
$ sh -c '{ readlink /proc/self/fd/0 <&3 3<&- & } 3<&0; wait' < /
/

另一种选择是使用即使在仿真zsh中也忽略该要求的方法:sh

$ zsh -c 'readlink /proc/self/fd/0 & wait' < /
/
$ zsh --emulate sh -c 'readlink /proc/self/fd/0 & wait' < /
/

相关内容