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

6

我有以下的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个回答

9

由于您正在使用管道,while循环正在子shell中运行。请改为在主shell中运行。

#!/bin/bash

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

以 sh 的身份调用 bash 会禁用某些功能,包括进程替换。 - Ignacio Vazquez-Abrams
+1,这对于一个四级管道在脚本中运行时仅出现故障的问题有所帮助。很奇怪的事情。 - l0b0
这将完全退出Putty。有没有办法只从while中退出? - Boris

3
根据Ignacio所说,你的tail | while创建了一个子shell。延迟是因为它在等待下一行被写入日志文件之前关闭所有内容。
如果您不想使用进程替换,可以在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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接