I need to be able to redirect output to a file and also check the return code of a script in KSH (can't use pipestatus or pipefail), I have found a solution but I'm not sure what the significance of file discriptor 4 is, can someone explain please?
{
rc=$(
{
{
. somescript.sh 2>&1
echo "$?" >&3
} | tee -a somefile.txt
} 3>&1 >&4 4>&-
)
} 4>&1
echo "${rc}"
rc=$(...)
means that the return code will be whatever is printed on file descriptor (fd) 1
by the code within the (...)
. So, somehow, what somescript.sh
outputs has to be moved off fd 1
and then brought back later. The echo
line outputs somescript.sh
's return code to fd 3
. Then, 3>&1
sends the saved return code to fd 1
, where $(...)
expects it. However, this means the old fd 1
(from {somescript 2>&1 } | tee
) doesn't have anywhere to go. So the old fd 1
is redirected to fd 4
with >&4
(and the input side is closed with 4>&-
since it won't be used). Then, once the $(...)
is over, the 4>&1
at the end puts the output of the somescript|tee
back onto fd 1
where other programs expect it to be.
Whew!
Without the >&4
, the output of somescript.sh
and the output of echo "$?"
would be mixed on fd 1
because of the 3>&1
. So fd 4
is a holding pen for the actual output of somescript.sh
during the time that fd 1
is being used to carry the return code.