你能帮我理解这种 bash 行为吗?后台进程及其对当前进程的附加

你能帮我理解这种 bash 行为吗?后台进程及其对当前进程的附加

我偶然发现了这种意想不到的行为,我希望有更了解的人可以解释它!

我有一个由脚本调用并作为后台进程运行的函数 -some_function &当我将它分配给变量时xxx=$(some function &),我注意到杀死脚本也杀死了这个进程。但是,当它没有分配给变量时,杀死脚本会使进程继续运行!

为什么是这样?我认为将命令分配给变量可以使其附加到脚本,这样杀死脚本也会杀死它吗?这对我有好处,我只是想了解它。该函数本身不返回任何内容。

这是代码:

screen_saver_function () { while true; do echo "some phrase"; done }
yyy=$(cat /dev/$tty > /tmp/tty &)
xxx=$(screen_saver_function > /dev/$tty &)
while true; do [[ ! -z $(cat /dev/$tty) ]] && break; done

我的想法是,我试图将 screen_saver_function 的输出传递到终端(第一行),然后在按下按键时终止。我通过将终端中的任何文本写入文件并在文本出现在该文件中时退出脚本来完成此操作。我知道这很糟糕,但它确实有效。我正在捕获$!当我遇到所描述的奇怪行为时,将其杀死以退出后台进程。

答案1

在 中xxx=$(some function &),是的,您在该子 shell 中异步运行some function,但其标准输出仍然连接到由命令替换创建的管道的写入端。

因此,虽然子 shell 在异步启动后会立即退出some function,但从该管道的读取端读取命令替换的输出以填充$xxx变量的父 shell 仍将等待该管道上的文件结尾,这在some function完成之前不会发生。

如果父 shell 被终止,则管道的读取端将关闭,并且some function下次尝试写入 stdout(进入管道)时将收到 SIGPIPE。

相关内容