2010-02-18 37 views
7

Chờ đợi không chờ tất cả các tiến trình con dừng lại. Đây là kịch bản của tôi:Làm cho lệnh "Chờ" của linux đợi cho TẤT CẢ các tiến trình con

#!/bin/bash 

titlename=`echo "[email protected]"|sed 's/\..\{3\}$//'` 
screen -X title "$titlename" 

/usr/lib/process.bash -verbose [email protected] 

wait 

bash -c "mail.bash [email protected]" 
screen -X title "$titlename.Done" 

Tôi không có quyền truy cập vào /usr/lib/process.bash, nhưng nó là một kịch bản thay đổi thường xuyên, vì vậy tôi muốn tham khảo nó ... nhưng trong kịch bản:

#!/bin/ksh 
#lots of random stuff 
/usr/lib/runall $path $auto $params > /dev/null 2>&1& 

vấn đề của tôi là runall tạo ra một tập tin đăng nhập ... và mail.bash là giả sử để gửi thư cho tôi rằng tập tin đăng nhập, nhưng sự chờ đợi là không chờ đợi runall để kết thúc, có vẻ như chỉ chờ đợi process.bash để hoàn tất. Dù sao, không truy cập vào quy trình .bash hoặc cố gắng giữ phiên bản cập nhật của riêng mình.bash, để chờ đợi chờ đợi runall hoàn tất? (Các tập tin log ghi đè chạy trước, vì vậy tôi không thể chỉ kiểm tra sự hiện diện của các tập tin đăng nhập, vì luôn luôn có ai ở đó)

Cảm ơn, Dan

+0

Bạn có thể cung cấp cho chúng với các bộ phận có liên quan của 'ps ef 'sau khi 'chờ đợi' đã kết thúc? Điều đó sẽ cho thấy các quy trình nào đang chạy và quá trình nào là một đứa trẻ trong đó quá trình khác ... – Heinzi

+0

Kịch bản của tôi và Process.bash kết thúc gần như ngay lập tức. Quá trình còn lại duy nhất là runall, chạy dưới PID ngẫu nhiên. – Dan

Trả lời

9
(
    . /usr/lib/process.bash -verbose $@ 
    wait 
) 

Thay vì để cho hệ điều hành bắt đầu process.bash, điều này tạo ra một subshell, chạy tất cả các lệnh trong process.bash như nếu chúng được nhập vào trong kịch bản lệnh shell của chúng ta và đợi trong subshell đó.

Có một số cảnh báo về điều này, nhưng nó sẽ hoạt động nếu bạn không làm gì bất thường.

+0

Chà ...vì vậy sau đó runall vì một quá trình con của kịch bản của tôi? Điều này làm việc như một say mê (tôi đã phải thay đổi kịch bản của tôi để ksh để phù hợp với process.bash). Ctrl + C chỉ dừng sự chờ đợi, thay vì runall ... Lý tưởng nhất là tôi chỉ có thể chạy process.bash mà không cần một "&", nhưng tôi không thể sửa đổi mã đó và không muốn tiếp tục cập nhật mã của tôi mỗi khi process.bash thay đổi. Cảm ơn. – Dan

+3

Để có Ctrl-C giết quá trình nền, sử dụng bẫy và giết: 'pid = $ !; bẫy "giết $ pid; chờ $ pid; thoát 0" SIGINT SIGTERM; đợi $ pid' –

4

wait chỉ chờ đợi cho trẻ em trực tiếp; nếu bất kỳ đứa trẻ nào sinh ra con cái của riêng mình, nó sẽ không chờ đợi chúng.

+0

Có cách nào xung quanh vấn đề này không? Nếu tôi muốn nó chờ đợi cho tất cả trẻ em, trực tiếp và gián tiếp? – Dan

+1

Cách duy nhất khác là chờ bằng PID hoặc jobspec. –

2

Vấn đề chính là vì process.bash đã thoát khỏi quy trình runall sẽ bị mồ côi và thuộc sở hữu của init (PID 1). Nếu bạn nhìn vào danh sách quá trình runall sẽ không có bất kỳ kết nối hiển thị nào với quy trình của bạn nữa kể từ khi tập lệnh trung gian process.bash thoát. Không có cách nào để sử dụng ps --ppid hoặc bất kỳ điều gì tương tự để tìm kiếm quy trình "cháu" này khi nó mồ côi.

Bạn có thể wait trên một PID cụ thể. Bạn có biết PID của quá trình runall không? Nếu chỉ có một quá trình như vậy, bạn có thể thử này, mà sẽ chờ đợi cho tất cả chạy runall s:

wait `pidof runall` 
+0

Điều này không hoạt động vì runall không phải là con của tập lệnh gốc. – abhaga

1

Bạn có thể hồi phục các PID của tiến trình cho người mà bạn muốn chờ

Và sau đó vượt qua PID này như một tham số cho lệnh Chờ

Các vấn đề liên quan