等待后台进程完成并反向匹配进程 ID

等待后台进程完成并反向匹配进程 ID

我希望在循环中运行多个后台进程,但只想等待所有这些进程完成,仍然允许另一个后台进程继续。

经过一些研究后,我只看到需要我列出我想要的每个进程 ID 的解决方案,wait而不是将它们与单个进程 ID 反向匹配。看来类似的东西wait != $pid会非常有用。

示例脚本:

#!/bin/bash

command1 &
pid=$!
for i in ${array[@]}; do
    for n in $(seq 3); do
        if [ $n -eq 1 ];
            command2 > file &
        else
            command2 >> file &
        fi
    done
done

在此示例中,我希望等待每个进程完成,除非$pid不必使用wait命令列出所有进程。这可能吗?

答案1

只是有什么问题

wait

help wait注释:

等待由 ID(可以是进程 ID 或作业规范)标识的进程,并报告其终止状态。如果未给出 ID,则等待所有当前活动的子进程,并且返回状态为零。

您想“仍然允许另一个后台进程继续”吗?只是disown它。按照你的例子:

command1 & disown %1
command2 & command2 & command2 &
wait

答案2

正如其他人所说,没有任何方法可以等待“不是”进程 ID。然而,这种代码模式对我来说似乎并没有那么糟糕,所以我将其作为实现您所追求的目标的建议方法提供。

它使用 Bash 数组,然后您可以将其作为列表提供给命令wait

例子

示例代码的修改版本,cmd.bash.

!/bin/bash

array[0]=1
array[0]=2

sleep 30 &
pid=$!

pidArr=()
for i in ${array[@]}; do
  for n in $(seq 3); do
    if [ $n -eq 1 ]; then
      sleep 31 > file &
      pidArr+=($!)
    else
      sleep 32 >> file &
      pidArr+=($!)
    fi
  done
done

echo ${pidArr[@]}

sleep在本例中替换了命令,只是为了模拟一些我们可以在后台运行的长时间运行的作业。他们除了充当替身之外,与此无关。

最后的命令也echo纯粹是为了让我们可以看到 for 循环完成时会发生什么。最终我们将用实际wait命令替换它,但我们不要超前。

示例运行 #1

那么让我们运行我们的程序,看看会发生什么。

$ ./cmd.bash 
24666 24667 24668

现在如果我们检查ps

$ ps -eaf|grep sleep
saml     24664     1  0 22:28 pts/9    00:00:00 sleep 30
saml     24666     1  0 22:28 pts/9    00:00:00 sleep 31
saml     24667     1  0 22:28 pts/9    00:00:00 sleep 32
saml     24668     1  0 22:28 pts/9    00:00:00 sleep 32

如果我们稍等一下,这些最终都会完成。但这表明,如果我们将进程 ID 添加到数组中,echo之后就可以将它们取出。

例子#2

因此,现在让我们更改该echo行并换入一行wait,如下所示:

  wait ${pidArr[@]}

现在,当我们运行修改后的版本时,我们看到它正在等待所有进程 ID:

$ ./cmd.bash 

...约 30 秒后

$

我们得到提示。这样我们就顺利的等待了所有的进程。快速检查ps

$ ps -eaf|grep sleep
$

所以它起作用了。

相关内容