2012-06-26 61 views
7

Tôi cần phải chạy ứng dụng trong mỗi X giây, vì vậy, như xa như cron không làm việc với giây theo cách này, tôi đã viết một kịch bản bash với vòng lặp vô hạn có X giây ngủ trong đó.Làm thế nào để dừng vòng lặp vô hạn trong kịch bản bash một cách duyên dáng?

Khi tôi phải dừng tập lệnh đang chạy theo cách thủ công, tôi muốn thực hiện theo cách chính xác - hãy để ứng dụng hoạt động hoàn chỉnh và không nhập vòng lặp cho lần tiếp theo.

Bạn có ý tưởng nào không, làm thế nào để đạt được điều này? Tôi nghĩ về việc vượt qua các đối số, nhưng tôi không thể tìm ra cách chuyển đối số cho tập lệnh đang chạy.

Trả lời

22

Bạn có thể bẫy một tín hiệu, nói SIGUSR1:

echo "My pid is: $$" 
finish=0 
trap 'finish=1' SIGUSR1 

while ((finish != 1)) 
do 
    stuff 
    sleep 42 
done 

Sau đó, khi bạn muốn thoát khỏi vòng lặp ở phiên bản kế tiếp:

kill -SIGUSR1 pid 

đâu pid là quá trình id của kịch bản. Nếu tín hiệu được nâng lên trong khi ngủ, nó sẽ thức giấc (ngủ cho đến khi có tín hiệu xảy ra).

+0

Thanks :) this works –

2

Bạn có thể chuyển một số đối số theo tệp. Trên mỗi lần lặp, bạn có thể đọc tệp này và xem liệu các điều hành đang chạy của bạn có thay đổi hay không.

1

Cấu trúc sau có thể phù hợp nếu bạn vẫn phải dọn dẹp. Sử dụng kill như thể hiện trong câu trả lời của cdarke.

#=============================================================== 
# FUNCTION DEFINITIONS 
#=============================================================== 
# . . . 

#=== FUNCTION ================================================ 
#   NAME: cleanup 
# DESCRIPTION: 
#=============================================================== 
cleanup() 
{ 
    # wait for active children, remove empty logfile, ..., exit 
    exit 0 
} # ---------- end of function cleanup ---------- 

#=============================================================== 
# TRAPS 
#=============================================================== 
trap cleanup SIGUSR1 

#=============================================================== 
# MAIN SCRIPT 
#=============================================================== 
echo -e "Script '$0'/PID ${$}" 

while : ; do        # infinite loop 
    # . . . 
    sleep 10 
done 
# . . . 

#=============================================================== 
# STATISTICS/CLEANUP 
#=============================================================== 
cleanup 
0

Giải pháp bẫy được đăng trước đó tốt cho các vòng lớn, nhưng cồng kềnh cho trường hợp thông thường bạn chỉ lặp qua một hoặc một vài lệnh. Trong trường hợp này, tôi khuyên bạn nên giải pháp sau:

while whatever; do 
    command || break 
done 

Điều này sẽ thoát khỏi vòng lặp nếu lệnh có mã thoát khác 0, sẽ xảy ra nếu nó bị gián đoạn. Vì vậy, trừ khi command xử lý SIGINT, nhấn ctrl-C cả hai sẽ dừng lệnh hiện tại và thoát khỏi vòng lặp.

Chỉnh sửa: Sau khi đọc câu hỏi của bạn chặt chẽ hơn, tôi thấy rằng bạn muốn lệnh hiện tại tiếp tục thực hiện. Trong trường hợp đó, giải pháp này không áp dụng.

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