6

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?

3 Answers 3

9

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 ...)
Sign up to request clarification or add additional context in comments.

3 Comments

Invoking bash as sh disables certain features, including process substitution.
+1, this helped with a four-level pipe which was breaking only when run in a script. Weird stuff.
This exits absolutely from Putty. Is there any way to exit just from while ?
3

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* ]].

Comments

2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.