So, I need to make a modification to a start script to clean up the /tmp once the application is fully loaded. After some research, I found a command for my script that does this:

tail -f /home/user1/logs/application.log | awk '/Application is fully up and running/ { system("pm2 restart cleantmp"); exit 1; }'

echo "Startup complete"

Basically, it checks each newline of the script for the pattern 'Application is fully up and running', and when that occurs, uses pm2 to restart a cleanup process we have.

This seems work as far as cleaning up /tmp after the application starts. However, I'm running into an issue where the console will then just hang there, showing me the server output, and never exiting. It does not fail or through an error; it simply never reaches the echo statement, and waits for me to use CTRL+C.

Based on my research on this site,I've tried other versions of this using tail and sed:

tail -f /home/user1/logs/application.log | grep --line-buffered -q 'Application is fully up and running' | while read ; do pm2 restart cleantmp ; done
tail -f /home/user1/logs/application.log | sed "/Application is fully up and running/q"

In both cases, the script did not even get to cleanup. Further testing with "ps -aux | grep tail" shows that it is definitely tail -f that is preventing the script from completing. Has anyone had a similar use case to this? Any suggestion would be greatly appreciated.



tail -f /home/user1/logs/application.log |
grep --line-buffered -q 'Application is fully up and running' |
while read ; do pm2 restart cleantmp ; done

you're using -q to tell grep to produce no output and then piping that nothing to a loop that's trying to read it. You could try just this instead:

tail -f /home/user1/logs/application.log |
grep --line-buffered -q -m 1 'Application is fully up and running'
pm2 restart cleantmp

but the tail won't terminate until the next line is written to the input file, which I assume from your problem statement doesn't happen, so you could write an empty line back to the input file from within the script that finds the string you're looking for just before that script exits:

tail -f "$file" |
awk -v file="$file" '/Application is fully up and running/{exit} END{print "" >> file}'
pm2 restart cleantmp

It's kinda hacky but should work as long as you don't mind a blank line being appended to the input file.

Finally, what I think is the simplest solution, is to forget about tail and just call awk in an infinite loop once per second til the string you want appears then break out of the loop:

while :; do
    awk '/Application is fully up and running/{f=1; exit} END{exit !f}' && break
    sleep 1
done < '/home/user1/logs/application.log'
pm2 restart cleantmp

That last assumes the final message you're looking for gets written to your log file as a single line.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.