2011-03-09 181 views
1

我正在使用zgrep - 在壓縮文件上運行grep的bash腳本包裝器。bash:退出腳本循環

問題是,控制 - c不會停止腳本。 我想是因爲循環遍歷文件,產生子shell,所以終止信號轉到正在運行的grep進程,而不是父腳本。所以即使陷入父母腳本也不行。

來說明:

trap break SIGPIPE SIGTERM SIGQUIT SIGSTOP 
for i 
    gzip -cdfq "$i" | grep $pattern 
done 

我也試過"/bin/kill -- -$$"代替break,具有相同的結果。我猜這個腳本沒有得到中斷。

任何想法如何解決這個問題?

回答

0

我很驚訝你的C-c不工作(你可能想看看stty)。不過,你的腳本有幾個問題。

  1. trap命令也應停止在SIGINT
  2. 陷阱中的break不會讓你走出循環。你會需要這樣的東西:
 
DONE= 
trap 'DONE=1' SIGINT 
for i in "[email protected]"; do 
    [[ -n $DONE ]] && break 
    ∶ 
0

bash信息文檔:

如果bash等待命令完成並接收信號 爲其陷阱已定,直到 命令完成後,陷阱纔會被執行。

如果你想改變它的話,你需要編寫一個封裝器來讓你更好地控制信號。

+0

是的,但是信號也會傳遞給程序,因此(通常)會盡早終止信號,然後陷阱會發出聰明的聲音。 – bobbogo 2011-03-14 18:43:21

0

我得到類似的陷阱行爲(沒有得到執行)。我的環境是HP Unix上的ksh88。我的陷阱是趕上INT KILLQUIT。我在shell函數中調用gzip。如果我刪除gzip陷阱處理程序得到執行時,我發送中斷信號,但不是當我有gzip

關於你的問題:Cntrl-C不會阻止你的循環的原因是因爲你正在捕捉你的陷阱。而你的陷阱處理程序是不正確的命令來停止你的循環。你的父母腳本不會停止,因爲它看不到任何信號,再次因爲'陷阱'你說你想處理它而不是殼。如果你只想退出循環,那麼把你的循環放在一個單獨的函數中,並在該函數中設置陷阱。只給你一個想法,這裏是a.ksh


function f1 
{ 
    trap return INT QUIT KILL 
    i=0 

    while [[ $i -lt 100 ]] 
    do 
     $((i=$i+1)) 
     sleep 2 
     echo $i 
     done 
} 

echo BEFORE calling f1 

f1 

echo AFTER calling f1 

測試。KSH:

$ a.ksh 

BEFORE calling f1 

1 

2 

3 

以後打電話F1


我第三次迭代後擊中Contrl-C。正如你看到我得到AFTER calling f1消息,這意味着contrl-C只是停止了功能不是整個過程(a.ksh)。希望有所幫助。