【问题标题】:How to capture PID of a background process如何捕获后台进程的PID
【发布时间】:2018-05-29 09:00:50
【问题描述】:

我对 BASH shell 如何分配 PID 有点困惑,所以我需要你的帮助来理解这一点,我想在这里解决一个问题。我在 shell 脚本中调用一个函数。该函数在后台运行另一个 groovy 脚本,如下所示:

fn_list()
{
... ... ... 
groovy list_gn.gy -p $prop_file $@ &
echo "Extracting PID No :$!" >> $logpid
}

我在循环中这样调用这个函数:

for x in `cat $list | grep -v '#'`; do
fn_list &
echo "Extracting function PID No :$!" >> $logpid
done

因为我在后台运行这个函数,而且这个函数运行的 groovy 也在后台运行(使用 &)。

我的问题是我正在记录函数的 PID,并且我还在记录从该函数内部调用的 groovy 脚本的 PID。函数的 PID 和从这个函数内部调用的 groovy 会不同吗?这是记录 PID 的正确方法吗?

我需要了解它的行为,因为我计划将函数进程分叉 3 次。所以要绝对确定这是否是正确的方法。

【问题讨论】:

  • 子进程在它们自己独立的 shell 中运行。只要您使用$!,您就可以安全地获取他们的 id,并且澄清一下,您的逻辑中的两个 id 会有所不同

标签: bash unix pid


【解决方案1】:

实际上pid不是由bash分配而是由操作系统分配的,当一个进程被分叉时,它被分配一个新的pid,从bash进程调用groovy .. &会创建一个新的子进程groovy,它是bash进程的父进程。

bash 函数调用不会创建新的 pid,因为它在与内置命令相同的进程中运行。

但是由于函数调用后的& 会创建一个新的bash 进程(子shell),所以可能不需要两个& 之一。

如果您对这些进程的结果感兴趣,您可能需要等待它们的执行,这就是 wait 内置函数所做的,可以考虑并行执行。

pids=()
for ... ; do
    groovy ... &
    pids+=( "$!" )
done

exit_codes=()
for pid in "${pid[@]}"; do
    wait "$pid"
    exit_codes+=( "$?" )
done

【讨论】:

  • 谢谢@Nahuel ...是的,您是对的,不需要在后台调用该函数。我现在只分叉 groovy 脚本。等待“$pid”解决了我的问题。这就是我想要确定的。感谢您的反馈。
  • 不客气,如果它解决了问题,请毫不犹豫地接受答案
  • @NahuelFouilleul 这看起来很优雅,知道为什么当我使用rsync 命令而不是groovy 尝试此代码时,无论执行次数如何,pids 数组都只包含一个 pid?
  • @ChenA。感谢您的评论,似乎 rsync 自己分叉了,也许关注会很有趣serverfault.com/questions/460423/…
猜你喜欢
  • 2012-02-27
  • 1970-01-01
  • 2011-01-26
  • 2020-03-24
  • 2012-03-21
  • 1970-01-01
  • 2017-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多