Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

So I want to do some logging and therefor, want to put a date in front of a bash script's output. The problem is that is has multiple lines of output. I am able to only put the date before the whole output. But then I have a line without a date in the logs. Of course I can assume the date from the line above is the same, but I was hoping there is a solution. Thanks in advance!

This is my script that calls another script:

#!/bin/sh
echo $(date "+%F %T") : starting script
echo $(date "+%F %T") : $(./script.sh)
echo $(date "+%F %T") :script ended

This is the output:

2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
second line of output
2012-07-26 15:35:17 : script ended

And thats what I would like to have:

2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
2012-07-26 15:35:15 : second line of output
2012-07-26 15:35:17 : script ended
share|improve this question
    
I don't suppose you could just just change the second script? –  mutzmatron Jul 26 '12 at 14:32
    
Nah, Unfortunately not. That's why I came here. –  tzippy Jul 26 '12 at 14:33
2  
add comment

4 Answers

up vote 6 down vote accepted

According to a similar question on Stack Overflow, there are 2 great options.

awk (Answer)

<command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }'

annotate (Answer)

annotate is a small bash script, that can either be directly obtained through the link provided here, or, on Debian based systems, through the package devscripts (in the form of annotate-output).

share|improve this answer
add comment

This will print the current date and time before each line of output of ./script.sh:

set -f
./script.sh | while read -r LINE; do echo $(date "+%F %T") : "$LINE"; done
set +f

How it works

  • set -f turns off bash expansion (or echo * wouldn't print an actual asterisk).

  • while read -r LINE; do ... done saves one line of output in the variable $LINE and executes ..., until all lines are processed.

  • echo $(date "+%F %T") : "$LINE" prints the line with the current time and date.

  • set +f turns bash expansion back on, so it won't interfere with the rest of your bash script.

share|improve this answer
    
It gets evaluated only once, so every sed inserts the same date, from just before starting the second script. Likely not what the user wants... –  Daniel Beck Jul 26 '12 at 14:37
    
I don't think this attempt will work either. AFAIK, the whole subshell gets evaluated completely first, then the loop is traversed. So now the times are from after the execution. –  Daniel Beck Jul 26 '12 at 14:49
    
Your example doesn't work, since you only delay output, not execution of ls. Just try your script with the following script.sh: #!/bin/bash (newline) echo 1 ; sleep 1 ; echo 2 ; sleep 2 ; echo 3 ; sleep 3 ; echo 4 –  Daniel Beck Jul 26 '12 at 14:56
    
Use read with a while loop instead of a for loop. –  chepner Jul 26 '12 at 15:01
    
@chepner: Good idea. –  Dennis Jul 26 '12 at 15:28
show 3 more comments

I think that you can use awk for this:

./script.sh | awk '{ print strftime()" : "$0; }'

(see http://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html for formatting the date returned by strftime())

share|improve this answer
1  
awk: calling undefined function strftime -- is this specific to gawk? –  Daniel Beck Jul 26 '12 at 14:50
    
Now that you mention it, yes it seems to be :/ –  epingle Jul 26 '12 at 15:29
add comment

You can use awk

./script.sh | awk '{ print d,$1}' "d=$(date "+%F %T")"

awk takes an input stream and modifies it's output. This script is saying "print d followed by the original output", then then populates d with the date.

share|improve this answer
1  
Doesn't this evaluate the date expression only once as well, so that all such lines print the same time? –  Daniel Beck Jul 26 '12 at 14:42
    
@DanielBeck Yes it does - I had assumed it was picking up the date each time but just finished my test quickly enough –  Paul Jul 26 '12 at 14:45
add comment

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.