2010-10-28 52 views
6

我有以下bash腳本:bash腳本不會立即退出時`exit`被稱爲

tail -F -n0 /private/var/log/system.log | while read line 
do 
    if [ ! `echo $line | grep -c 'launchd'` -eq 0 ]; then 
     echo 'launchd message' 
     exit 0 
    fi 
done 

出於某種原因,這是呼應launchd message,等待了整整5秒,然後退出

爲什麼會發生這種情況,如何在響應後立即退出launchd message

回答

9

由於您正在使用管道,while循環正在一個子shell中運行。改爲在主外殼中運行它。

#!/bin/bash 

while ... 
do 
    ... 
done < <(tail ...) 
+0

我在做線得到一個語法錯誤... – Chetan 2010-10-29 01:48:45

+0

啊,那是因爲我是用/ bin/sh的,愚蠢的我。 – Chetan 2010-10-29 02:00:42

+0

調用bash作爲sh會禁用某些功能,包括進程替換。 – 2010-10-29 02:04:43

3

正如Ignacio所示,您的tail | while創建了一個子外殼。延遲是因爲它在等待下一行被寫入日誌文件之前一切都關閉。

您可以立即加入這一行你exit命令之前,如果你不想使用進程替換:

kill -SIGPIPE $$ 

不幸的是,我不知道有什麼辦法來控制使用這種方法的退出代碼。它將是141 + 128 + 13(信號編號SIGPIPE)。

如果你想讓一個守護進程的啓動依賴另一個守護進程啓動,那麼可能有更好的方法。順便說一句,如果你真的寫了一個Bash腳本(你必須使用<()進程替代),你可以這樣編寫ifif [[ $line == *launchd* ]]

2

您也可以用告訴退出代碼退出子shell,然後測試「$?」的值。讓你在尋找同樣的效果:

tail -F -n0 /private/var/log/system.log | while read line 
do 
    if [ ! `echo $line | grep -c 'launchd'` -eq 0 ]; then 
     echo 'launchd message' 
     exit 10 
    fi 
done 
if [ $? -eq 10 ]; then exit 0; fi