Skip to content
Advertisement

Redirecting output of a program to a rotating file

I am trying to redirect the output of a continuously running program to a file say error_log.

The command I am using looks like this, where myprogram.sh runs continuously generating data and writing to /var/log/httpd/error_log

  • myprogram.sh >> /var/log/httpd/error_log

Now I am using logrotate to rotate this file per hour. I am using create command in logrotate so that it renames the original file and creates a new one. The logrotate config looks like

/var/log/httpd/error_log {
# copytruncate
 create
 rotate 4
 dateext
 missingok
 ifempty
 .
 .
 .
}

But here redirection fails. What I want is myprogram.sh to write data to error_log file irrespective of it being rotated by logrotate, obviously to newly generated error_log file

Any idea how to make redirection work based on the file name and not the descriptor ?

OR

Any other way of doing it in bash ?

Advertisement

Answer

If I understood your problem, one solution (without modify myprogram.sh) could be:

$ myprogram.sh | while true; do head -10 >> /var/log/httpd/error_log; done

Explaining:

  • myprogram.sh writes to stdout
  • We redirect this output to while bash sentence through a pipe |.
  • while true is an infinite loop that will never end, nor even when myprogram.sh ends which should break the pipe.
  • In each loop head command is called to append the first 10 lines read from the pipe to the end of current /var/log/httpd/error_log file (that may be different from the last loop because of logrotate).

(You can change the number of lines being written in each loop)

And another way is:

$ myprogram.sh | while read line; do echo "$line" >> /var/log/httpd/error_log; done
  • That’s very similar to the first one, but this ends the loop when myprogram.sh ends or closes it’s stdout.
  • It works line by line instead in groups of lines.
Advertisement