1

A Bash script runs a program in the background and redirects stdout of that program to a file. How can I kill the program if it hasn’t written to stdout for the last x seconds?

prog > out.txt &
PID=$!
...
wait $PID

I imagine to pipe the output through some other program that checks for continuing output. unbuffer could be necessary to disables output buffering.

unbuffer prog | ... > out.txt &
1

2 Answers 2

1

You can use /usr/bin/inotifywait inside your script, without the -m option, so monitoring stops at the first write event, and with the -t 10 option so the process exits with code 2 if no write-modification event was registered within the last 10s:

#!/usr/bin/env bash

my_prog > out.txt &
my_prog_pid="$!"
my_watch_status=0

while [ "$my_watch_status" != "2" ]; do
    /usr/bin/inotifywait -qq -t 10 -e modify out.txt 2>/dev/null & 
    wait $!
    my_watch_status="$?"
done

kill -9 "$my_prog_pid"
exit <my exit_code>
  • Option -qq ("very quiet") and redirection of standard error to /dev/null are meant to suppress any inotifywait diagnostic information on standard error and event information on standard output.
  • Every time out.txt is written to (within a 10s time window), a new 10s monitoring time window is started.
  • kill -9, aka SIGKILL, is used for not knowing better about possible requirements for you to exit my_prog in an orderly fashion. If a graceful exit is preferable, a simple kill "$my_prog_pid" can be used.
  • The script kills my_prog and exits, optionally with your choice of exit code, only when no write-modification of out.txt has occurred within the prescribed time window.
  • Note that, during execution, the time window is not a perfect 10s. The actual time-window will be a little more than 10s (think "ms" for one file) because it takes a little time to establish monitoring. This is unsubstantial in your case, because you monitor only one file, but it could become quite substantial if you were to monitor a large tree (think of a directory structure with thousands of files) in a recursive manner. If the 10s time window is application-critical, you might want to explore other methods than the one proposed here, to not have to reestablish monitoring every time-window span or, as a worst-case scenario, everytime a write event occurs within that time span.
1
  • Amazing! That’s exactly what I was looking for! Smart idea to monitor the file for changes. The solution is very elegant as it can be implemented in the same script that starts the program. Thank you very much!
    – bivox
    Jun 22 at 20:23
-2

It could be something like:

#!/bin/bash

while read line -t 10
do
   echo $line
done

if [ $? -gt 128 ]
then
  echo "Timeout occurred"
  killall -SIGKILL procces
fi
1
  • Thank you for your answer! You directly address my question about a script/program that can monitor the stdout of the program.
    – bivox
    Jun 22 at 20:22

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.