I have a script which always giving output where I have it redirected to a file, what I'm trying to do is to rotate the redirected file, below is where i start the script and redirect it:

su - username -c "command >> /path/to/directory/output.txt" &
code continues..

and below is the crontab I'm trying to create:

cd /path/to/directory/
timestamp=`date "+%Y%m%d"`
mv ./output.txt ./logs/output.txt_$timestamp
touch output.txt
chmod 757 ./output.txt
gzip ./logs/output.txt_$timestamp
find ./logs/output.txt* -type f -mtime +2 | xargs rm

or this one also failed to do the job:

timestamp=`date "+%Y%m%d"`
cp ./output.txt ./logs/output.txt_$timestamp
echo "" > ./output.txt
gzip ./logs/output.txt_$timestamp

in the first code the original script fails and is no longer working, and in the second script it doesn't clean the output.txt file.

Is there a way to do it while keeping the script working ? Note; I'm running Unix Solaris.

Thanks in advance.


This is typically done by adding a SIGHUP handler which restarts the command after some other command (typically logrotate) has moved the file. On *nix operating systems you can move files while they are being written to (I believe with the caveat that it has to still be on the same filesystem); the extra lines will be appended to the file in the new location.


You really can't change a running process's redirected stdout and/or stderr to a new file (see note below) (That's one reason using redirected stdout or stderr as log files for long-running processes is a bad idea.)

When the process is started, the redirection elements of the command are executed by the shell that starts the process. The target file is opened and created if necessary in the proper mode (append or overwrite), and possibly truncated to zero bytes depending on redirection mode. Then the open file descriptor is passed to the child process. That open file descriptor is the only link to the redirected file that the child process has - literally. It's a link to the file.

And that's an important point - as a link directly to the file, the open descriptor is on par with the directory entry for the file - the "file name". Changing that name or even deleting that directory entry - such as with the rm command - has absolutely no effect on the open file descriptor in the process.

@l0b0's answer is correct that processes that need to rotate logs tend to use SIGHUP handlers to do such rotations, but "rotating logs" is not really that simple in the case of redirected output - what does the new output file get named? The child process has no idea of what the "name" of it's stdout and/or stderr are - and the output "file" might not even be a file in the first place.

Log rotation schemes have to be designed into the process - logging should to be integrated in such a way that log entries don't get lost in the midst of rotating the log file, for example.

(OK, it can be possible to change the stdout/stderr streams for a running process - but it's something that has to be - again - designed into the process. It's not something an out-of-the-box binary such as bash will do automagically if you send it a SIGHUP...)


Thanks alot all for you replies, couldn't find a way to do it, so as a workaround i setup the crontab to stop the original script, do the rotation and start it again at off peak.

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.