调用`exit`时,Bash脚本不会立即退出

时间:2010-10-28 22:22:55

标签: bash scripting exit terminate

我有以下bash脚本:

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之后立即退出?

3 个答案:

答案 0 :(得分:9)

由于您正在使用管道,while循环正在子shell中运行。而是在主shell中运行它。

#!/bin/bash

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

答案 1 :(得分:3)

如Ignacio所示,您的tail | while会创建一个子shell。延迟是因为它等待下一行在所有内容关闭之前写入日志文件。

如果您不想使用流程替换,可以在exit命令之前立即添加此行:

kill -SIGPIPE $$

不幸的是,我不知道使用此方法控制退出代码的任何方法。它将是141,即128 + 13(信号号SIGPIPE)。

如果你试图使一个守护进程的启动依赖于另一个已启动的守护进程,那么可能有更好的方法。

顺便说一句,如果您真的在编写Bash脚本(您必须使用<()进程替换),您可以像这样编写if:{{1 }}

答案 2 :(得分:2)

您也可以使用tell-tale退出代码退出子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