Skip to content
Advertisement

Shell script: Redirect output of program to changing files

My goal:

I would like to redirect the stdout output of my program foo to a changing output file depending on the running time of the program.

The program foo itself is listening on a bsd socket for arriving packets and displays information contained in them.
So essentially, after running the program foo for 10 minutes, I would like to have the stdout output of

  • the first minute inside the file bar_0.dat
  • the second minute inside the file bar_1.dat
  • the 10th minute inside the file bar_9.dat

Is it possible to achieve this in a shell script and if yes, how could I accomplish this?

What I have managed so far:

I only managed this solution, where the program is restarted after each minute with the redirection to a new output file:

#!/bin/bash
for i in {0..9}
do
  timeout 60s foo > "bar_${i}.dat"
done

However, I want the program foo to be running continuously and not having to restart it, because in the way I have realized it I am loosing some arriving packets (there is a 20-30ms gap between the running instances).

Advertisement

Answer

If foo is producing text output, you might get away with something like:

#!/bin/bash

stamp=0
i=0
redirect() {
        if test "$(date +%s)" -gt "$((stamp + 60))"; then
                stamp=$(date +%s)
                exec > "bar_$((i++)).dat"
        fi
}
redirect
./foo | while read line; do
        echo "$line"
        redirect
done

If foo is not producing text output, you’ll probably want to write foo so that it accepts an external input (eg, a signal) and redirects output on its own. Or, you might just want to use logrotate.

Advertisement