为什么这个命令替换要等待后台作业完成?

Why is this command substitution waiting for the background job to finish?

我正在尝试通过命令替换获取后台作业的 PID。后台作业从 setsid 开始。问题是父进程在命令替换时被击中。

这是一个示例脚本:

#!/bin/bash

if [ "" = "start" ]; then
    while true; do date > "bg.date"; sleep 1; done &
    echo $!
    exit 0
fi

pid="$(setsid "[=10=]" start)"
echo "pid=$pid"

命令替换是通过管道实现的。读取端等待所有写入器关闭,但您将写入端无限期地保持打开状态作为无限循环的标准输出。

您可以重定向循环以避免这种情况:

#!/bin/bash

if [ "" = "start" ]; then
    while true; do date > "bg.date"; sleep 1; done > /dev/null &
    echo $!
    exit 0
fi

pid="$(setsid "[=10=]" start)"
echo "pid=$pid"

如果重入者 setsid 是试图使脚本不挂起的一部分,您会很高兴知道这是不必要的,并且您可以使用一个简单的函数更可靠地重写它。