Erika
Erika

Reputation: 75

Getting out of tail -f in shell script

I cant seem to make this work. This is the script.

tail -fn0 nohup.out | while read line; do

    if [[ "${line}" =~ ".*ERIKA.*" ]]; then

        echo "match found"
        break

    fi

done

echo "Search done"

The code echo "Search done" does not run even after a match has been found. I just want the rest of the code to be ran when a match has been found. I have not made it possible yet.

Sorry, I am new with log monitoring. Is there any workaround with this?

I am gonna run the script via Jenkins so, the code should be free flowing and should not require any user interaction.

Please help, thanks.

Upvotes: 2

Views: 1376

Answers (3)

R Perrin
R Perrin

Reputation: 481

You've got a couple of issues here:

  1. tail is going to keep running until it fails to write to its output pipeline, and thus your pipeline won't complete until tail exits. It won't do that until after your script exits, AND another line (or possibly 4K if buffering, see below) is written to the log file, causing it to attempt to write to its output pipe. (re buffering: Most programs are switched to 4K buffering when writing through pipes. Unless tail explicitly sets its buffering, this would affect the above behaviour).

  2. your regex: "${line}" =~ ".*ERIKA.*" does not match for me. However, "${line}" =~ "ERIKA" does match.

You can use tail's --pid option as a solution to the first issue. Here's an example, reworking your script to use that option:

while read line; do
    if [[ "${line}" =~ "ERIKA" ]]; then
        echo "match found"
        break
    fi
done < <(tail --pid=$$ -f /tmp/out)

echo "Search done"

Glenn Jackman's pkill solution is another approach to terminating the tail.

Perhaps consider doing this in something other than bash: perl has a nice File::Tail module that implements the tail behaviour.

There are many more questions related to this problem, you may find something you prefer in their answers:

Upvotes: 3

anubhava
anubhava

Reputation: 784878

You can use awk to exit:

tail -fn0 nohup.out | awk '/ERIKA/{print "match found ", $0; exit}'

Upvotes: 0

glenn jackman
glenn jackman

Reputation: 246744

Here's one way, doesn't feel very elegant though.

tail -fn0 nohup.out |
while IFS= read -r line; do
    if [[ $line == *ERIKA* ]]; then
        echo "match found"
        pkill -P $$ tail
    fi
done

echo "Search done"

Upvotes: 0

Related Questions