我需要能够将输出重定向到文件并检查KSH中的脚本的返回码(不能使用pipestatus或pipefail),我找到了解决方案,但我不确定是什么意思文件描述符4是,有人可以解释一下吗?
{
rc=$(
{
{
. somescript.sh 2>&1
echo "$?" >&3
} | tee -a somefile.txt
} 3>&1 >&4 4>&-
)
} 4>&1
echo "${rc}"
答案 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.sh
,echo "$?"
的输出和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
退出。