I need to redirect ALL output to one file, and in addition redirect stderr to another file. Can this be done easily?
Let's assume my command for the purposes of this example is:
php /tmp/doWork.php
I can get output to separate files by using:
php /tmp/doWork.php 1> /tmp/stdout_file 2> /tmp/stderr_file
Based on this, I attempted:
php /tmp/doWork.php &> /tmp/stdboth_file 2> /tmp/stderr_file
but this just put stdout and stderr in /tmp/stdboth_file
and never wrote to /tmp/stderr_file
.
Best Answer
With
zsh
(andzsh
only) and itsmultios
feature:As fd 2 is redirected twice,
zsh
implements an internaltee
to have it sent to both files.With
bash
(or any Bourne-like shell (other thanzsh
where you'd need to disablemultios
for it to work here)), you can do thetee
ing by hand with:(though you lose the exit status of
your-cmd
.zsh
has it in$pipestatus[1]
,bash
in"${PIPESTATUS[0]}"
though (provided the redirection intostderr+stdout.log
didn't fail)).To record the pid of
your-cmd
, you could do:With
yash
and it's process redirection feature:(but note that
yash
will not wait for the termination of thattee
command, so the log files may not be complete by the time you run the next command after that).Something similar (and with the same caveat) can be done with process substitution in
bash
,zsh
andksh93
:To run in background and get the pid:
With
rc
:rc
's pipes allow specifying which file descriptors are connected to the pipe. With other shells, it's always fd 1 of the left command and fd 0 of the right one (hence the little dance with fd 3 above to shift file descriptors around).rc
will report failure if eitheryour-cmd
ortee
fails, though the exact number may be lost.