1

我正在尝试使用命令替换来获取后台作业的 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(除非后台作业被手动终止)。
4

1 回答 1

2

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

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

#!/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是尝试使脚本不挂起的一部分,您会很高兴知道这是不必要的,您可以使用简单的函数更健壮地重写它。

于 2018-07-24T22:24:29.630 回答