Redirection after prepending timestamp

Hi all,
I have little experience with Scripting so hoping someone may be able to help me or point me in the right direction.
I have a shell script which was outputting uncaught exceptions to a log file.
$JAVA_MAIN_CLASS > $LOGNAME 2>&1

What I want to be able to do is prepend a timestamp on each entry to the log file. I updated the script as follows:
$JAVA_MAIN_CLASS | perl -pne 'print scalar(localtime()), " ";' > $LOGNAME 2>&1

But nothing gets outputted to the file until the process is terminated and at that there is information missing. It is hard to tell if it is standard out or standard error. I know the perl timestamp part works as I have tested. But its when I try to pipe it to the file I am doing something wrong. :wall:

If anyone has any ideas I would appreciate them.

That's not how pipes work. Unless perl reads in the log entry in the first place it can't print it back out.

Try:

$JAVA_MAIN_CLASS | while read LINE
do
        perl -pne 'print scalar(localtime()), " ";'
        echo "$LINE"
done > logfile

There's probably a snappier and perl-less solution but without knowing what your system and shell is I can't know what date utilities, version of awk, etc. you have available.

Thanks Corona688.
I had just figured out that it was the pipe that was causing the error only standard out was getting through, standard error was getting lost.
Sorry if this sounds dumb but how can I find out
"what date utilities, version of awk, etc.you have available."

It wasn't quite the pipe that was doing it, it was that you were piping it into a program that didn't use it, so the data just stopped there.

I just realized you wanted stderr and stdout. slight change:

$JAVA_MAIN_CLASS 2>&1 | while read LINE
do
        perl -pne 'print scalar(localtime()), " ";'
        echo "$LINE"
done > logfile

Please tell me what your system is, and tell me what your shell is. :slight_smile: That'll be enough to find out most of the rest.

Systen is SunOS 5.10 Generic_142909-17 sun4u sparc SUNW,Sun-Fire-V240
Would I be better off trying to use awk rather than perl? As I had tried (not very hard) with awk but couldnt get it to work so I then just used perl.

GNU awk and GNU date have extensions to make timestamps easy but you don't have them. Perl seems to work.

Does the above script do what you want? Or did you only want timestamps on stdout, or stderr, not both?

I want timestamp on both. I have yet to try with your improved solution. Can I ask why why I need to echo "$LINE" ?

A pipe sends the output of the command in front of it to the command behind it and nowhere else. By piping it into the while loop, we've redirected it away from the terminal. So if that didn't print it -- nothing would. And if it didn't read it, nothing would.

Nearly there. Would like to be able to make a slight modification but not sure if it will be possible. If I test with a error stack trace each line is prepended with the date but all I need is the date to be prepended at the start of the exception. e.g
current output:

Fri Mar 11 09:11:18 2011 java.lang.RuntimeException: Exception for standard err
Fri Mar 11 09:11:18 2011        at main.Main.main(Main.java:13)
Fri Mar 11 09:11:18 2011        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Fri Mar 11 09:11:18 2011        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
Fri Mar 11 09:11:18 2011        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
Fri Mar 11 09:11:18 2011        at java.lang.reflect.Method.invoke(Method.java:592)
Fri Mar 11 09:11:18 2011        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)

desired output:

Fri Mar 11 09:11:18 2011 java.lang.RuntimeException: Exception for standard err
at main.Main.main(Main.java:13)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:592)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)

Not sure if that will be possible though.