Shell中用until循环等待多进程运行的条件判断问题
解决until循环多进程等待的问题
我来帮你搞定这个多进程等待的问题!首先得搞清楚为什么你用[[ ]]或[ ]会报错——这是因为[和[[是测试命令,它们需要的是具体的判断表达式(比如字符串非空、数值比较等),而直接把pgrep放进去的话,当进程不存在时,pgrep没有输出,就会变成[[ ]]这种语法错误的写法。
其实根本不需要用括号,我们可以直接利用命令的退出码来组合条件,这也是shell脚本里判断命令执行状态的标准方式:
核心思路
until循环的逻辑是:直到后面的命令返回退出码0(成功),才停止循环。而pgrep的特性是:
- 找到进程时,返回退出码0(成功),同时输出PID到stdout
- 找不到进程时,返回退出码1(失败),无输出
所以要等待多个进程全部启动,只需要用&&把多个pgrep命令串起来就行——&&表示“前面的命令成功,才执行后面的命令”,只有所有pgrep都返回0时,整个命令链的退出码才是0,until就会终止循环。
具体示例
比如你要等待proc1、proc2、proc3三个进程都运行起来,写法如下:
until pgrep proc1 >/dev/null && pgrep proc2 >/dev/null && pgrep proc3 >/dev/null; do echo "Waiting for all processes to start..." sleep 1 # 加sleep避免频繁轮询占用CPU done
- 加
>/dev/null是为了抑制pgrep输出的PID,避免干扰你的提示信息 sleep 1很重要,不然循环会疯狂执行,占用大量系统资源
如果你一定要用测试命令([[ ]])
虽然没必要,但如果想搞懂怎么用括号实现,你可以通过捕获pgrep的输出来判断:
until [[ -n "$(pgrep proc1)" && -n "$(pgrep proc2)" && -n "$(pgrep proc3)" ]]; do echo "Waiting..." sleep 1 done
这里-n用来检查字符串非空——当pgrep找到进程时,会输出PID(非空字符串),判断为真;找不到时输出空,判断为假。但这种写法比直接用命令退出码冗余,不推荐。
额外说明
如果你的需求是等待任意一个进程启动,把&&换成||就行:
until pgrep proc1 >/dev/null || pgrep proc2 >/dev/null; do echo "Waiting for either process to start..." sleep 1 done
内容的提问来源于stack exchange,提问作者Alex Parker
相关产品推荐
相关产品推荐

