匹配在Bash中并行运行的函数的输出

时间:2019-10-17 08:33:32

标签: bash gnu-parallel

我的Bash脚本大致如下:

#!/bin/bash
function a { echo -n "A is running..."; sleep 5; echo "done (A)" }
function b { echo -n "B is running..."; sleep 1; echo "done (B)" }
function c { echo -n "C is running..."; sleep 3; echo "done (C)" }

a
b
c

因为这三个操作都不是宇宙中最快的,所以我正在考虑通过并行运行来加快运行速度,就像这样:

a & b & c & wait

但是,这会将输出弄乱了,就像这样:

[1] 21405
A is running...[2] 21406
B is running...[3] 21408
C is running...done (B)
[2]  - 21406 done       b
done (A)
[1]  - 21405 done       a
done (C)
[3]  + 21408 done       c

理想情况下,我希望输出与原始作业的输出相似,并且流程按固定顺序排列,以便用户可以看到当前正在运行的内容:

A is running...done (A)
B is running...done (B)
C is running...done (C)

这意味着当B完成时,我想要这样的东西:

A is running...
B is running...done (B)
C is running...

有可能吗?在不重写太多功能(最好是)的情况下,实现此目标的好方法是什么?

还有一个相关说明,是否可以添加一个断路器,即如果B发生故障,A和C自动终止?

1 个答案:

答案 0 :(得分:0)

#!/bin/bash                                                                     
function a { sleep 8; }                                                         
function b { sleep 10; }                                                        
function c { sleep 5; }                                                         

a &                                                                             
b &                                                                             
c &                                                                             

echo 'a is running.'                                                            
echo 'b is running.'                                                            
echo 'c is running.'                                                            

while true; do                                                                  
        wait -n                                                                 

        A=`jobs -l | cut -b2`                                                   


        echo -n -e "\e[3A"                                                      
        if [[ $A =~ 1 ]]; then                                                  
                echo 'a is running.'                                            
        else                                                                    
                echo 'a is running... (done).'                                  
        fi                                                                      
        if [[ $A =~ 2 ]]; then                                                  
                echo 'b is running.'                                            
        else                                                                    
                echo 'b is running... (done).'                                  
        fi                                                                      
        if [[ $A =~ 3 ]]; then                                                  
                echo 'c is running.'                                            
        else                                                                    
                echo 'c is running... (done).'                                  
        fi                                                                      

        if [ -z "$A" ]; then break; fi                                          
done

请注意,命令echo -n -e "\e[3A"将光标向上移动3行。