2011-07-20 28 views
5

Tôi đã xem các chương trình giám sát hoặc trong các kịch bản kiểm tra tình trạng quá trình sử dụng 'ps' hoặc 'tình trạng dịch vụ (trên Linux)' định kỳ, hoặc trong C/C++ mà dĩa và chờ ... Quá trình này ...bash khởi động lại quá trình con bằng cách sử dụng bẫy SIGCHLD?

I tự hỏi nếu nó có thể sử dụng bash với bẫy và khởi động lại quá trình con khi SIGCLD nhận được?

tôi đã thử nghiệm một bộ cơ bản trên RedHat Linux với sau ý tưởng (và chắc chắn nó đã không làm việc ...)

#!/bin/bash 
set -o monitor # can someone explain this? discussion on Internet say this is needed 
trap startProcess SIGCHLD 
startProcess() { 
    /path/to/another/bash/script.sh & # the one to restart 
    while [ 1 ] 
    do 
    sleep 60 
    done 
} 
startProcess 

những gì kịch bản bash được bắt đầu chỉ ngủ trong vài giây và thoát cho hiện nay.

một số vấn đề quan sát:

  • khi vỏ bắt đầu trong foreground, SIGCHLD sẽ được xử lý chỉ một lần. bẫy đặt lại tín hiệu xử lý như tín hiệu()?
  • tập lệnh và con của nó dường như miễn nhiễm với SIGINT, có nghĩa là chúng không thể bị dừng lại bởi^C
  • vì không thể đóng được, tôi đã đóng thiết bị đầu cuối. Kịch bản dường như là HUP và nhiều trẻ em bị bỏ rơi.
  • khi chạy ở chế độ nền, kịch bản gây ra thiết bị đầu cuối để chết

... dù sao, điều này không làm việc ở tất cả. Tôi phải nói rằng tôi biết quá ít về chủ đề này. Ai đó có thể đề xuất hoặc đưa ra một số ví dụ làm việc? Có tập lệnh nào để sử dụng như vậy không?

làm thế nào để sử dụng chờ trong bash?

Cảm ơn

Trả lời

6

tôi có thể cố gắng trả lời một số câu hỏi của bạn, nhưng không phải tất cả dựa trên những gì tôi biết.

  1. Dòng set -o monitor (hoặc tương đương, set -m) bật công việc kiểm soát, mà chỉ là theo mặc định cho các hệ vỏ tương tác. Điều này có vẻ như cần được gửi cho SIGCHLD. Tuy nhiên, kiểm soát công việc có nhiều hơn một tính năng tương tác và không thực sự có ý nghĩa để được sử dụng trong các kịch bản lệnh vỏ (xem thêm this question).

    Cũng nên nhớ điều này có lẽ không phải những gì bạn dự định để làm bởi vì một khi bạn kích hoạt điều khiển công việc, SIGCHLD sẽ được gửi cho mỗi lệnh bên ngoài mà tồn tại (ví dụ như mỗi khi bạn chạy ls hoặc grep hoặc bất cứ điều gì , SIGCHLD sẽ kích hoạt khi lệnh đó hoàn thành và bẫy của bạn sẽ chạy).

  2. Tôi nghi ngờ lý do bẫy SIGCHLD chỉ xuất hiện để chạy một lần là vì trình xử lý bẫy của bạn chứa vòng lặp vô hạn phía trước, do đó đoạn mã của bạn bị kẹt trong trình xử lý bẫy. Có vẻ như không phải là điểm cho vòng lặp đó, vì vậy bạn có thể chỉ cần xóa nó.

  3. "khả năng miễn dịch" của tập lệnh đối với SIGINT có vẻ là tác động của việc bật điều khiển công việc (phần màn hình). Linh cảm của tôi là với kiểm soát công việc bật, trường hợp của bash chạy script của bạn không còn chấm dứt chính nó để đáp ứng với một SIGINT nhưng thay vì chuyển SIGINT thông qua để quá trình con foreground của nó. Trong kịch bản của bạn, ví dụ: ^C SIGINT chỉ đơn giản là hành động như một tuyên bố continue bằng các ngôn ngữ lập trình khác trường hợp, vì SIGINT sẽ chỉ giết hiện đang chạy sleep 60, và rồi vòng lặp while ngay lập tức sẽ chạy một mới sleep 60.

  4. Khi tôi thử chạy tập lệnh của bạn và sau đó giết nó (từ một thiết bị đầu cuối ), tất cả những gì tôi đã kết thúc là hai quy trình ngủ đi lạc.

  5. Bối cảnh kịch bản đó cũng giết vỏ của tôi đối với tôi, mặc dù hành vi không phù hợp khủng khiếp (đôi khi nó xảy ra ngay lập tức, thời gian khác không hề). Có vẻ như gõ bất kỳ phím nào khác hơn nhập gây ra một EOF để được gửi bằng cách nào đó. Ngay cả sau khi thiết bị đầu cuối thoát khỏi tập lệnh vẫn tiếp tục chạy trong nền. Tôi không có ý tưởng những gì đang diễn ra ở đây.

Cụ thể hơn về những gì bạn muốn thực hiện sẽ hữu ích. Nếu bạn chỉ muốn một lệnh để chạy liên tục trong suốt cuộc đời của kịch bản của bạn, bạn có thể chạy một vòng lặp vô hạn trong nền, như

while true; do 
    some-command 
    echo some-command finished 
    echo restarting some-command ... 
done & 

Lưu ý & sau done.

Đối với các tác vụ khác, wait có lẽ là ý tưởng tốt hơn so với sử dụng điều khiển công việc trong tập lệnh trình bao. Một lần nữa, nó sẽ phụ thuộc vào chính xác những gì bạn đang cố gắng để làm.

+0

Cảm ơn Jimmy, vì đã chia sẻ và thậm chí đã thử nghiệm kịch bản khủng khiếp. Tôi đã ngừng nỗ lực, sử dụng cách 'truyền thống' để làm điều đó - một vòng lặp và kiểm tra một. Tuy nhiên, tôi đã thử nghiệm "chờ", nó thực sự hoạt động rất tốt trong các tình huống cơ bản. ! '#/Bin/bash thepid = 0 stopnow = 0 set -o dõi bẫy dọn dẹp SIGINT SIGTERM dọn dẹp() { bẫy - SIGINT SIGTERM stopnow = 1 nếu [$ {} thepid -ne 0] sau đó vang giết $ {} thepid kill $ {} thepid fi } khi [$ {} stopnow -ne 1] làm echo bắt đầu ./trial.sh & thepid = $! echo "đang chờ $ {thepid}" chờ $ {thepid} được thực hiện thoát 0 ' –

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