2012-03-02 25 views
5

Tôi đang viết một tập lệnh bash để sinh ra một số quy trình nền. Tôi muốn được thông báo bất cứ khi nào một quá trình chấm dứt; và tôi muốn biết pid của quá trình chấm dứt.chụp pid quá trình nền đã kết thúc bằng bẫy trong bash

Tôi đã xem xét sử dụng wait, sao cho các pids của mỗi quá trình sinh ra được bắt và lưu trữ trong một mảng, sau đó mảng được lặp lại và chờ đợi được gọi trên mỗi quá trình. Kỹ thuật này được mô tả theo những cách khác nhau ở đây:

https://stackoverflow.com/a/356154/366856

Vấn đề với điều này, nếu tôi hiểu nó một cách chính xác, là nó có thể tương đối không hiệu quả nếu bạn muốn thực hiện một số hành động càng sớm càng một chấm dứt quá trình cá nhân . Ví dụ, nếu bạn sinh ra các tiến trình A và B, và B kết thúc trước A, thì việc thực hiện phải đợi cho cả A và B kết thúc. Tôi cần phải thực hiện một hành động ngay khi B kết thúc.

Có vẻ như trap SIGCHLD là cách để thực hiện hành động ngay lập tức khi trẻ chấm dứt, nhưng vấn đề là tôi không thể tìm cách xác định pid của nguồn tín hiệu SIGCHLD mà tôi cũng cần. Điều gần nhất tôi đã tìm thấy một ví dụ làm việc của điều này là ví dụ mã thứ ba trong bài viết này:

http://www.linuxforums.org/forum/programming-scripting/103996-multithreading-bash.html#post510187

Tôi đã copy-dán nó vào đây để tiện theo dõi:

#!/bin/bash 

iNext=0 

function ChildReturned() { 
     wait $1 
     echo "$1 was returned. Its exits status was: $?" 
     iNext=$((iNext+1)) 
     StartChild $iNext 
} 


function StartChild { 
     ./child $1 & 
     pid=$! 
     echo "Started: $1 PID= $pid" 
     trap 'ChildReturned $pid' SIGCHLD 
} 


set -bm 

for ((iNext=0; iNext<=10; iNext++)); 
do 
     StartChild $iNext 
done 

wait 

tôi nghĩ rằng ví dụ này không hiệu quả, bởi vì tác giả mắc lỗi khi gọi số trap nhiều lần, mỗi lần ghi lại một biến pid khác trong đối số trap. Mỗi lần bẫy được gọi, nó sẽ ghi đè cuộc gọi trước đó, và do đó một pid tùy ý sẽ bị bắt. Tôi đã không thể tìm ra một kỹ thuật tốt hơn.

Có cách nào để có được pid của một quá trình con chấm dứt bằng cách sử dụng bẫy trong bash?

Cập nhật

Tôi chỉ muốn để trỏ đến khu vực này, trong đó có các, cái nhìn tổng quan toàn diện nhất tốt nhất các giải pháp cho vấn đề này mà tôi đã thấy cho đến nay:

http://mywiki.wooledge.org/ProcessManagement#I_want_to_process_a_bunch_of_files_in_parallel.2C_and_when_one_finishes.2C_I_want_to_start_the_next._And_I_want_to_make_sure_there_are_exactly_5_jobs_running_at_a_time.

+2

http://mywiki.wooledge.org/ProcessManagement – jordanm

+0

'kill -0 $ PID': rất hữu ích! cảm ơn! – jbeard4

+0

Thậm chí tốt hơn, phần được gọi là * Tôi muốn xử lý một loạt các tệp song song và khi kết thúc, tôi muốn bắt đầu tiếp theo. Và tôi muốn đảm bảo có đúng 5 công việc đang chạy tại một thời điểm. * Câu trả lời hay nhất mà tôi đã đọc cho đến nay – jbeard4

Trả lời

3

Đặt bẫy một lần và trong bẫy bạn có thể gọi jobs -n để xem trẻ nào đã kết thúc kể từ lần cuối bạn kiểm tra. Lưu ý rằng điều này không cho bạn biết đứa trẻ nào đã gửi SIGCHLD; xem xét trường hợp hai đứa trẻ chết trước khi bạn vào bẫy. Trong trường hợp đó, bạn sẽ chỉ nhập bẫy một lần và đó là điểm tranh luận mà tín hiệu của con bạn thực sự phản hồi. Lưu ý rằng -n là tiện ích mở rộng bash và bạn có thể thích sử dụng jobs -l.

+0

Thật tuyệt, tôi không biết về 'công việc-n'.Tôi nghĩ rằng điều này sẽ khá tốt giải quyết vấn đề của tôi, và vì vậy tôi sẽ đánh dấu câu hỏi này là giải quyết. – jbeard4

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