Shell script chờ lệnh nền


12

Tôi đang viết một kịch bản, nhưng có một thứ tôi cần mà tôi không thể tìm ra cách để làm nó ...

Tôi cần phải thực hiện một lệnh trong nền "lệnh1 &" và sau đó ở đâu đó trong tập lệnh tôi cần đợi nó kết thúc trước khi tôi thực hiện lệnh2. Về cơ bản, tôi cần điều này:

LƯU Ý: mỗi lệnh chạy trong một thư mục cụ thể! ở cuối vòng lặp while, lệnh1 của tôi đã tạo 4 thư mục, trong đó mỗi vòng chạy một quy trình cụ thể để tổng số tiến trình đang chạy là 4

a=1

while [$a -lt 4 ]

     . command1
   #Generates 1 Process  

     a= `export $a +1`
done

   #Wait until the 4 process end and then run the command2 

    . command2

Tôi đã thấy một cái gì đó về một waitlệnh với số tiến trình pid, nhưng nó cũng không hoạt động.


Bạn có kiểm soát command1không? Bạn có thể sửa đổi nó để nó trả về các PID của 4 quy trình không?
terdon

Đúng! tôi đã có nó rồi :)
Joao Macau

Tôi đã cập nhật câu trả lời của tôi cho phù hợp. Hãy cho tôi biết nếu nó phù hợp với quan điểm của bạn.
Laurent C.

Q này có liên quan đến cái này: unix.stackexchange.com/questions/100801/iêu . Sự khác biệt duy nhất là bạn cần có được PID từ một quá trình nền. Bạn có thể sử dụng $!biến để lấy cái này, chuyển nó tới waitlệnh như tôi đã chỉ ra ở đó. $!chứa PID nền cuối cùng, trong khi $$chứa PID của quá trình chạy cuối cùng.
slm

3
OK, bây giờ kịch bản của bạn không có ý nghĩa gì cả. Có lỗi cú pháp và sự kỳ lạ xung quanh. Bạn có thể chỉ cho chúng tôi kịch bản thực tế ? Tại sao bạn tìm nguồn cung ứng các lệnh? Tại sao không thực hiện chúng?
terdon

Câu trả lời:


22

Bạn có thể sử dụng lệnh wait PIDđể chờ một quá trình kết thúc.

Bạn cũng có thể truy xuất PID của lệnh cuối cùng với $!

Trong trường hợp của bạn, một cái gì đó như thế này sẽ hoạt động:

command1 & #run command1 in background
PID=$! #catch the last PID, here from command1
command2 #run command2 while command1 is running in background
wait $PID #wait for command1, in background, to end
command3 #execute once command1 ended

Theo chỉnh sửa của bạn, vì bạn có nhiều PID và bạn biết chúng, bạn có thể làm điều đó:

command1 & #run command1 in background
PID1=xxxxx
PID2=yyyyy
PID3=xxyyy
PID4=yyxxx
command2 #run command2 while command1 is running in background
wait $PID1 $PID2 $PID3 $PID4 #wait for the four processes of command1, in background, to end
command3 #execute once command1 ended

Sau khi chỉnh sửa, nếu bạn biết PID được tạo (xxxxx, yyyyy, xxyyy, yyxxx), bạn cũng có thể sử dụng Wait, với danh sách các PID để chờ (xem man). Nếu bạn không biết họ, có lẽ bạn có thể tập hợp họ vào lệnh1 (lệnh1 là gì? Kịch bản của riêng bạn?)
Laurent C.

Có lẽ tốt nhất để đảm bảo chúng được nhóm chính xác ở vị trí đầu tiên. Xem câu trả lời của tôi cho một ý tưởng về cách nó có thể được thực hiện.
mikeerv

4

Cách sạch nhất để làm điều này là yêu cầu comamnd1trả lại các PID của các quy trình đã khởi chạy và sử dụng waitcho từng quy trình theo đề xuất của câu trả lời của @ LaurentC .

Một cách tiếp cận khác sẽ là như thế này:

## Create a log file
logfile=$(mktemp)

## Run your command and have it print into the log file
## when it's finsihed.
command1 && echo 1 > $logfile &

## Wait for it. The [ ! -s $logfile ] is true while the file is 
## empty. The -s means "check that the file is NOT empty" so ! -s
## means the opposite, check that the file IS empty. So, since
## the command above will print into the file as soon as it's finished
## this loop will run as long as  the previous command si runnning.
while [ ! -s $logfile ]; do sleep 1; done

## continue
command2

xin lỗi nhưng vẫn không hoạt động .. tôi sẽ cải thiện câu hỏi của tôi một lần nữa!
Joao Macau

0

Nếu bạn sử dụng phương pháp sau, bạn có thể không cần "chờ tất cả các quy trình" đặc biệt sau vòng lặp while. Vòng lặp sẽ đợi dòng điện command1hoàn thành trước khi nó quay trở lại đầu trang. Hãy sử dụng cẩn thận như với bất kỳ lời khuyên. Lưu ý, điều duy nhất tôi đã làm là thêm & wait $!vào cuối của bạn command1.

a=1
while [$a -lt 4 ]
     . command1  & wait $!
   #Generates 1 Process  
     a= `export $a +1`
done
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.