1

A similar question as been asked here

But it wont work for me

"shell.ksh"  > >(tee here.log ) 2> >(tee err.log)
ksh: 0403-057 Syntax error: `>' is not expected.

this command will not redirect stderr just stdop

"shell.ksh" | tee file.log 2>&1 

I am on AIX running some UNIX similar to BSD that does not have GNU extensions and this is ksh

ps $$
      PID    TTY STAT  TIME COMMAND
 40632390  pts/6 A     0:00 -ksh

Any short and sweet solns folks ?

Community
  • 1
  • 1
user1874594
  • 2,277
  • 1
  • 25
  • 49

1 Answers1

1

Here is a wrapper script that should do what you want. I can't confirm that it works on AIX ksh, but it works using sh (AT&T Research) 93u+ 2012-08-01 (Debian's ksh package calls it the "Real, AT&T version of the Korn shell." This is intentionally neither pdksh nor its mksh fork).

This is portable and should work in all POSIX shells.

pipe1+2.ksh

#!/bin/ksh

touch err.log here.log      # create the logs now so tail -f doesn't complain
tail -f here.log &          # follow the output we'll pipe to later (run in bg)
HERE=$!                     # save the process ID of this backgrounded process
tail -f err.log >&2 &       # follow output (as above), pipe output to stderr
ERR=$!                      # save the process ID

"$@" > here.log 2> err.log  # run given command and pipe stdout and stderr
RET=$?                      # save return value

sleep 1                     # tail polls at 1/s, so wait one second

kill $HERE $ERR             # stop following those logs

exit $RET                   # restore the exit code from given command

So you invoke it as pipe1+2.ksh shell.ksh (assuming both commands are in your path).

Here's a test version of shell.ksh:

#!/bin/ksh

echo this output is stdout 1
echo this output is stderr >&2
echo this output is stdout 2

and a trial run:

# ksh pipe1+2.ksh ksh shell.ksh
this output is stdout 1
this output is stdout 2
this output is stderr
# cat here.log
this output is stdout 1
this output is stdout 2
# cat err.log
this output is stderr

A note: because tail -f isn't instantaneous, stdout vs stderr will be slightly out of order. It won't even be consistent between runs, at least with code that runs as fast as echo.

I doubt your version of tail supports it, but GNU tail has a -s SECONDS flag that lets you specify a different polling interval as a decimal value, so you can try e.g. tail -f -s 0.01 … to improve the ordering of what is displayed. If your version of sleep also supports decimal values, change it to match that number.

 

(I had originally crafted a complicated file descriptor piping response based on one of the "more elaborate combinations" in the amazing Csh Programming Considered Harmful, but that didn't seem to work. See the comments and/or the initial version of this answer.)

Adam Katz
  • 14,455
  • 5
  • 68
  • 83
  • Hey Adam ! Thanks for your response. I ran it ditto like above on the command line. It did nothing on the screen no o/p `exec 3>&1; "test.sh" 2>&1 1>&3 3>&- |tee err.log 1>&2 3>&- |tee here.log` and it did not write to log either `0 Feb 22 01:09 here.log 0 Feb 22 01:09 err.log` – user1874594 Feb 22 '16 at 07:12
  • Okay. I was worried about that. `tee` seems to play oddly with that logic even in other shells. Not much consistency there. I've therefore rewritten the whole thing with a wrapper script. – Adam Katz Feb 22 '16 at 18:58
  • TY SM. Works as expected for above. – user1874594 Feb 23 '16 at 07:40