I need to run a program called pg.sh. It report stdout to output log. How do I save stdout and both stderr and stdout into 2 separate log files?
I searched and got the below code
(pg.sh 2>&1 1>&3 ) 3>&1 1>&2 | tee output.log) > final.log 2>&1
I understand 1 and 2 are File Descriptors pointing to stdout and stderr. 3 is another File Descriptor pointing to stdout.
The above code works fine, But I do not understand how this is being achieved. Could some one help me with the code written?
starting from the outer redirection: ( .. ) 3>&1 1>&2
, the order is important:
the |
input is then the fd 3, whereas the stderr is not captured by tee,
The nested redirection:
fd 2 is redirected to stdout (which was redirected to outer stderr)
fd 1 is redirected to fd 3 (which was redirected to outer stdout)
as tee duplicates output logged, (the final redirection >final.log 2>&1
, as the fd 2 is open after fd 1 they are both redirected to final.log)
the file final.log will contain program stdout and stderr, but output.log only stdout.
Maybe it could be written easier, using 3>&1 1>&2 2>&3
which reverses stdout and stderr.
The following should do the same:
( pg.sh | tee output.log ) >final.log 2>&1
The following writes program stdout to output.log stderr to error.log and both to final.log.
( ( pg.sh | tee output.log ) 3>&1 1>&2 2>&3 | tee error.log ) >final.log 2>&1