如何使反引号在后台作业的 shell 脚本上执行

如何使反引号在后台作业的 shell 脚本上执行

该命令不会终止

echo `bash -c 'tail -f /dev/null & echo hello world'`

尽管事实上

bash -c 'tail -f /dev/null & echo hello world'

正确返回“hello world”

我正在尝试将 bash 脚本中的命令置于后台,该命令在反引号内进行评估。我实际上需要运行 eval 而不是 echo,在这个例子中我使用的是 echo。有问题的脚本模拟一个 ssh 代理,它通常输出许多导出语句。但是,在脚本中我需要后台工作。

我尝试使用disown,nohup$()代替反引号。看来反引号总是等待所有子进程的终止。有办法绕过这个吗?我特别有兴趣接收后台命令的 PID。

答案1

在:

echo `shell code`

以下是已弃用的形式:

echo $(shell code)

shell code在子 shell 中求值,并且它的所有的输出,删除尾随换行符,并且由于您忘记引用它,因此将 split+glob 作为参数传递给echo.

为此,shell 使该子 shell 的 stdout 成为一个管道,并且在管道的另一端,shell 读取输出直到文件末尾,即直到所有具有其 stdout(或任何其他fd) 在该管道上打开,关闭这些 fd 或终止。

在:

echo "$(sleep 10 & echo done)"

即使sleep 10是异步运行并且子 shell 不等待其终止,运行的进程sleep仍然在管道上打开其 stdout (fd 1),并且它将保持这种状态直到它退出,因此 shell 必须等待直到sleep终止知道没有更多输出可供读取。

如果你把它改成:

echo "$(sleep 10 > /dev/null & echo done)"

您会看到它sleep在后台运行时立即返回,因为sleep在这种情况下管道上没有打开任何 fd。

答案2

我特别有兴趣接收后台命令的 PID。

我猜你想要 pid tail,而不是bash.

你不必bash -c只使用

tail -f /dev/null & echo $!

相关内容