为什么这个命令替换要等待后台作业完成?
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"
./script start
按预期工作(即当后台作业为 运行 时立即退出到 bash 提示符)。
setsid ./script start
也按预期工作。
- 但是
./script
没有按预期工作:它不打印 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
是试图使脚本不挂起的一部分,您会很高兴知道这是不必要的,并且您可以使用一个简单的函数更可靠地重写它。
我正在尝试通过命令替换获取后台作业的 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"
./script start
按预期工作(即当后台作业为 运行 时立即退出到 bash 提示符)。setsid ./script start
也按预期工作。- 但是
./script
没有按预期工作:它不打印 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
是试图使脚本不挂起的一部分,您会很高兴知道这是不必要的,并且您可以使用一个简单的函数更可靠地重写它。