I would like to create a pipe in a ksh script (using exec) that pipe's to a tee, and sends the output to a pipe.
Current:
#Redirect EVERYTHING
exec 3>&1 #Save STDOUT as 3
exec 4>&2 #Save STDERR as 4
exec 1>${Log} #Redirect STDOUT to a log
exec 2>&1 #Redirect STDERR to STDOUT
What'd I'd like to do (but I don't have the syntax correct):
#Redirect EVERYTHING
exec 3>&1 #Save STDOUT as 3
exec 4>&2 #Save STDERR as 4
exec 1>tee -a ${Log} >&3 #Redirect STDOUT to a log
exec 2>&1 #Redirect STDERR to STDOUT
How can I create this pipe?
I worked out a solution using named pipes.
Instead of:
exec 1>tee -a ${Log} >&3
do simply:
tee -a ${Log} >&3 &
tee
will fork into the background, and will consume the calling process' (i.e. your script's) STDIN as it was at the time thattee
forked.I know bash not ksh, but there's a lot of overlap, so maybe this will work there too.
Creates a subshell running process2. That subshell receives as its stdin the data from process1's file descriptor N. So in particular, you could do:
I don't know whether this would also work if
process1
is replaced withexec
, but you could give it a try.Here's a solution I use. It works under ksh on my Mac. It's nicely encapsulated into start_logging() and stop_logging() functions to make life easy.
The code looks like this in practice:
Here is the whole file. The start and stop functions along with the example above are all at the bottom of the file. To make it easier to use, just put the start and stop functions in their own file and source them in the scripts where you need the logging.
There are
|&
and>&p
in ksh, but I couldn't get them to do what you're looking for. Maybe you can.