如何防止bash子shell等待子进程

问题描述 投票:0回答:2

我有一个 bash 脚本,除其他外,它还启动后台进程。我使用一个函数为进程设置一些配置,启动它,检查它是否正确启动,然后返回它的 PID,稍后用它来终止子进程。下面的示例代码具有相同的结构,但简化了逻辑:

function launcher(){
    sleep 30 &
    echo $!
}


PID=$(launcher)
echo $PID
kill $PID

我面临的问题是,执行

launcher
函数的子 shell 在
sleep
命令结束之前不会返回。因此,直到子 shell 结束时才会执行
echo $PID
语句。

令我惊讶的是,如果我检查

sleep
命令,它没有脚本作为父 ID:

UID        PID  PPID  C STIME TTY      STAT   TIME CMD
user     20135     1  0 18:39 pts/8    S+     0:00 sleep 30

如何在后台启动

sleep &
,让子shell在结束之前结束?

注意:请注意,在我的例子中,后台进程永远不会结束,直到我杀死它,所以我需要子shell来结束获取PID。另请注意,在我的实际代码中,

launcher
函数的逻辑非常复杂,我将其作为子shell运行以将主进程与其隔离。

提前致谢

bash shell
2个回答
2
投票

问题恰好与

stdin
有关,因为主 shell 正在从子 shell 的
stdout
读取内容,而该子 shell 是由后台进程继承的。只需在调用后台进程时重定向
stdout
即可使其按预期工作。

sleep 100 > /dev/null &

0
投票

我不确定这是否能完成但是

function launcher(){
    echo "start launching"
    sleep 100  &
    echo "end launching"
}

launcher
PID=$!

# Here $PID is the process id of `sleep`
echo $PID
kill $PID

如果没有

kill
,这将运行分叉的
sleep
命令,并且 shell 脚本结束,留下
sleep
命令以
PID
中设置的 pid 运行,这意味着您可以稍后杀死它。

这是您需要的吗? 如果没有,你能澄清一下你的期望吗?

我还注意到,如果父脚本保持活动状态,则睡眠进程的 PPID 是正确的并且保持不变。

# sleeper_test.sh
#!/bin/bash
function launcher(){
    echo "start launching"
    sleep 100  &
    echo "end launching"
}

launcher
PID=$!

# Here $PID is the process id of `sleep`
echo $PID

sleep 10
#kill $PID

$ ps -ef | grep sleep
  501 13748  5471   0  1:54PM ttys000    0:00.00 /bin/bash ./sleeper_test.sh
  501 13749 13748   0  1:54PM ttys000    0:00.00 sleep 100 <- child correctly tied to the parent sh script
  501 13750 13748   0  1:54PM ttys000    0:00.00 sleep 10
$ ps -ef | grep sleep
  501 13749     1   0  1:54PM ttys000    0:00.00 sleep 100 <- since the parent ended - it's parent becomes the root process parent
``
© www.soinside.com 2019 - 2024. All rights reserved.