Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have an issue with a shell script that uses rsync to synchronize 2 directories. I'm storing the result of the rsync command (whether it's successful or not) to a file named status and in case there is a problem, the stderr output is appended to a file named error. However, I can't seem to find a way to enter a timestamp before the actual error in the error file.

In the end, I need something like this:

if rsync source destination 2>> error # but I need to have the date before the actual error is appended!
then
   echo "`date` - Success" >> status
else
   echo "`date` - Failure" >> status
fi

I've also tried the following:

(rsync source destination && echo "`date` - Success" >> status || echo "`date` - Failure" >> status) 2>>error

The only way I've made this work is when I store the stderr output to a temporary file, so that I can append its contents to the error file after I have entered the timestamp.

share|improve this question
    
You have two different files: status and error and your two examples don't agree on what output goes where. Can you describe exactly what you want to do? –  jw013 Dec 28 '11 at 16:53
    
On an unrelated note, assuming that you want stdout and stderr to go to the same place, you should remember that stdout is usually buffered whereas stderr is not, which means stderr will almost always arrive before stdout if both go to the same place. –  jw013 Dec 28 '11 at 16:54
    
You are right, I've just edited it! I'll try to explain what I want a bit clearer: the status file should contain only the date and a success or failure entry, while the error file should contain the date and the output of stderr (in case there is an error, of course). –  IG83 Dec 29 '11 at 6:34

3 Answers 3

up vote 1 down vote accepted

Have you tried this?

rsync -av blah blah 2>&1|perl -e "while(<>){s/^/`date`  /g; print;}" >>logfile

It will add the date and some spaces to the beginning of the line.

share|improve this answer
    
Perfect! This does exactly what I want! –  IG83 Jan 2 '12 at 7:51
    
Hi again! Is there a way to insert an IF statement in there, in order to have the Success/Failure messages appended to another file (check my description)? –  IG83 Jan 2 '12 at 18:34

Greg's Wiki has an entry on adding timestamps to every line of a stream that covers several methods, depending on your environment. They all come down to piping the stream through a loop/process that adds in the timestamps; the POSIX-compliant version is:

while IFS= read -r line; do
    echo "$(date +%Y%m%d-%H:%M:%S) $line"
done
share|improve this answer
    
also: mywiki.wooledge.org/BashFAQ/082 –  Samus_ Dec 29 '11 at 0:05
4  
Rather than just provide a link, please at least include a brief summary in your answer... –  jasonwryan Dec 29 '11 at 6:42
    
the links says everything that needs to be said, and that site is great for learning bash; you will click it. –  Samus_ Dec 29 '11 at 22:48
1  
Yes, it is a great reference. However, this site is a wiki, not a link farm. Downvoting. Happy to restore your point when you update your response... –  jasonwryan Dec 30 '11 at 8:03
1  
@Samus_ We really do prefer if the answers are capable of standing alone, in case the link breaks or users have already seen it and decided it's not helpful (there are a number of meta.SO questions about this, particularly Are answers that just contain links elsewhere really “good answers”?). I edited yours this time; we typically just leave a comment and delete them –  Michael Mrozek Dec 30 '11 at 23:21

I know it's been more than 3 months since I asked this question, but I thought it would be nice to show what I ended up doing in my shell script.

As I've described, I needed to somehow catch stderr, in order to manipulate it in a log file, e.g. add a timestamp. I was able to do this using files and with what Patrick suggested, but I wanted to keep it as simple as possible.

So, this is how I worked it out:

if ! result=$(command_that_will_produce_errors 2>&1 1>/dev/null)
then
    echo "There was an error on $(date): $result" >> logfile
else
    echo "Command executed successfully on $(date)" >> logfile
fi
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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