Score:3

Capture script output to add datetime to ouput in realtime

cn flag

I'm looking to capture the output of a shell script execution in real time to enrich it with information giving the date and time.

To illustrate, I have for example a script of this type that I must not modify:

#!/bin/bash
for i in 2 3 1
do
  echo "Waiting for $i seconds ..."
  sleep $i
done

The script produces the following output:

Waiting for 2 seconds ...
Waiting for 3 seconds ...
Waiting for 1 seconds ...

I am trying to produce the output of the type:

2021-06-16 11:44:48 [INFO] Waiting for 2 seconds ...
2021-06-16 11:44:50 [INFO] Waiting for 3 seconds ...
2021-06-16 11:44:53 [INFO] Waiting for 1 seconds ...

I use the following shell functions for formatting in a script that runs my initial script:

function log {
   echo `date +%Y-%m-%d" "%H:%M:%S`" $@"
   if [ "$LOGFILE" != "" ]
   then
      echo `date +%Y-%m-%d" "%H:%M:%S`" $@" >>$LOGFILE
   fi
}

function loginf {
   log "[INFO] $@"
}

I manage very well with a while loop on a read to capture the output of my script, but I get all the lines at the same time (end of its execution) and therefore all lines have the same datetime. I try to get the lines each time the script produces a line and not at the end of the execution.

pLumo avatar
in flag
How do you call your initital script? This works well for me : `./script1.sh | while IFS= read -r l; do loginf "$l"; done`. See also https://serverfault.com/questions/72744/command-to-prepend-string-to-each-line
bac0n avatar
cn flag
`./script.sh | ts "%Y-%m-%d %H:%M:%S [INFO]"`
raj avatar
cn flag
raj
I created a script that contains your two functions and then the following code: `while { read; } do loginf $REPLY; done`. Running `./script1 | ./script2` (where `script1` is your first script and `script2` the above mentioned script) gives correct output for me, ie. different timestamps.
bac0n avatar
cn flag
don't need to use `echo` really, could just do `f(){ date "+%Y-%m-%d %H:%M:%S [INFO] $*"; }; f one two three`
bac0n avatar
cn flag
`f(){ printf '%(%Y-%m-%d %H:%M:%S)T [%s] %s\n' -1 INFO "$*"; }; f one two three` even better...
Score:2
us flag

The ts command from package moreutils does precisely what you are looking for:

./script.sh | ts

It has various options for formatting the time stamp. For instance,

ts '%F %T [INFO]'

will give you the exact format you use in your question.

Score:0
cn flag
vog

You can either use ts:

./your_script.sh | ts

Of, if you need something portable that works on systems where ts is not installed, you can do that in a simple while loop using the built-in read command:

./your_script.sh | while read line; do echo "$(date +'%Y-%m-%d %H:%M:%S') [INFO] $line"; done
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.