Соответствующий вывод из функций, работающих параллельно в Bash - PullRequest
3 голосов
/ 17 октября 2019

Мой сценарий 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 голосов
/ 17 октября 2019
#!/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 строки вверх.

...