输出文件描述符重定向

时间:2016-10-04 14:32:02

标签: ksh file-descriptor

我需要能够将输出重定向到文件并检查KSH中的脚本的返回码(不能使用pipestatus或pipefail),我找到了解决方案,但我不确定是什么意思文件描述符4是,有人可以解释一下吗?

{
rc=$(
{
  {
    . somescript.sh 2>&1
    echo "$?" >&3
  } | tee -a somefile.txt
} 3>&1 >&4 4>&-
)
} 4>&1

echo "${rc}"

2 个答案:

答案 0 :(得分:2)

rc=$(...)表示返回代码将是1内代码在文件描述符(fd)(...)上打印的内容。所以,不知何故,somescript.sh输出必须从fd 1移出然后再带回来。 echo行将somescript.sh的返回码输出到fd 3。然后,3>&1将保存的返回代码发送到fd 1,其中$(...)期望它。但是,这意味着旧的fd 1(来自{somescript 2>&1 } | tee)无处可去。因此旧的fd 1被重定向到带有4的fd >&4(输入端由4>&-关闭,因为它不会被使用)。然后,一旦$(...)结束,最后的4>&1会将somescript|tee的输出放回fd 1,而其他程序会在其中预期。{/ p >

呼!

如果没有>&4,由于somescript.shecho "$?"的输出和1的输出将在fd 3>&1上混合。所以fd 4是fd somescript.sh用于携带返回码的时间内1实际输出的握笔。

答案 1 :(得分:1)

如果您愿意使用命名管道,则可以省去所有文件描述符争论:

mkfifo p
tee -a somefile.txt < p &
. somescript.sh > p
rc=$?

在这里,我们在后台运行tee,让它从命名管道p读取其输入。一旦该作业启动,我们就会获取脚本并将其输出重定向到命名管道。脚本完成后,您可以使用普通的赋值语句将其退出状态保存到rc。这也将关闭管道的末端,这将导致另一端关闭,并允许tee退出。