我正试图通过命令替换来获取后台作业的PID。后台作业以setsid
启动。问题是父进程在命令替换时受到了冲击。
下面是一个示例脚本:
#!/bin/bash
if [ "$1" = "start" ]; then
while true; do date > "bg.date"; sleep 1; done &
echo $!
exit 0
fi
pid="$(setsid "$0" start)"
echo "pid=$pid"
./script start
按预期工作(即在后台作业运行时立即退出以获得bash提示(setsid ./script start
也如预期的那样工作- 但
./script
并没有按预期工作:它不会打印PID(除非后台作业被手动终止(
命令替换是通过管道实现的。读取端等待所有写入程序关闭,但您将无限期地保持写入端打开,作为无限循环的stdout。
您可以重定向循环以避免这种情况:
#!/bin/bash
if [ "$1" = "start" ]; then
while true; do date > "bg.date"; sleep 1; done > /dev/null &
echo $!
exit 0
fi
pid="$(setsid "$0" start)"
echo "pid=$pid"
如果重新进入的setsid
是使脚本不挂起的尝试的一部分,那么您将很高兴知道这是不必要的,并且您可以用一个简单的函数更健壮地重写它。