Question

I have the following bash script:

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

For some reason, it is echoing launchd message, waiting for a full 5 seconds, and then exiting.

Why is this happening and how do I make it exit immediately after it echos launchd message?

Was it helpful?

Solution

Since you're using a pipe, the while loop is being run in a subshell. Run it in the main shell instead.

#!/bin/bash

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

OTHER TIPS

As indicated by Ignacio, your tail | while creates a subshell. The delay is because it's waiting for the next line to be written to the log file before everything closes.

You can add this line immediately before your exit command if you'd prefer not using process substitution:

kill -SIGPIPE $$

Unfortunately, I don't know of any way to control the exit code using this method. It will be 141 which is 128 + 13 (the signal number of SIGPIPE).

If you're trying to make the startup of a daemon dependent on another one having started, there's probably a better way to do that.

By the way, if you're really writing a Bash script (which you'd have to be to use <() process substitution), you can write your if like this: if [[ $line == *launchd* ]].

You can also exit the subshell with a tell-tale exit code and then test the value of "$?" to get the same effect you're looking for:

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top