输出文件描述符重定向
output file descriptor redirection
我需要能够将输出重定向到文件并检查 KSH 中脚本的 return 代码(不能使用 pipestatus 或 pipefail),我找到了解决方案,但我不确定文件描述符 4 的意义是什么,有人可以解释一下吗?
{
rc=$(
{
{
. somescript.sh 2>&1
echo "$?" >&3
} | tee -a somefile.txt
} 3>&1 >&4 4>&-
)
} 4>&1
echo "${rc}"
rc=$(...)
表示 return 代码将是 (...)
中的代码打印在文件描述符 (fd) 1
上的任何内容。因此,不知何故,somescript.sh
输出必须从 fd 1
中移出,然后再带回来。 echo
行将 somescript.sh
的 return 代码输出到 fd 3
。然后,3>&1
将保存的 return 代码发送到 $(...)
期望的 fd 1
。但是,这意味着旧的 fd 1
(来自 {somescript 2>&1 } | tee
)无处可去。所以旧的 fd 1
被重定向到 fd 4
和 >&4
(并且输入端被 4>&-
关闭,因为它不会被使用)。然后,一旦 $(...)
结束,末尾的 4>&1
会将 somescript|tee
的输出放回 fd 1
其他程序期望的位置。
哇!
如果没有 >&4
,由于 3>&1
,somescript.sh
的输出和 echo "$?"
的输出将在 fd 1
上混合。所以fd4
是在fd1
携带return代码的时候somescript.sh
的实际输出的握笔
如果您愿意使用命名管道,则可以免除所有文件描述符争论:
mkfifo p
tee -a somefile.txt < p &
. somescript.sh > p
rc=$?
在这里,我们 运行 tee
在后台,让它从命名管道 p
读取输入。该作业启动后,我们获取脚本并将其输出重定向到命名管道。脚本完成后,您可以使用普通赋值语句将其退出状态保存到 rc
。这也将关闭管道的外壳端,这将导致另一端也关闭并允许 tee
退出。
我需要能够将输出重定向到文件并检查 KSH 中脚本的 return 代码(不能使用 pipestatus 或 pipefail),我找到了解决方案,但我不确定文件描述符 4 的意义是什么,有人可以解释一下吗?
{
rc=$(
{
{
. somescript.sh 2>&1
echo "$?" >&3
} | tee -a somefile.txt
} 3>&1 >&4 4>&-
)
} 4>&1
echo "${rc}"
rc=$(...)
表示 return 代码将是 (...)
中的代码打印在文件描述符 (fd) 1
上的任何内容。因此,不知何故,somescript.sh
输出必须从 fd 1
中移出,然后再带回来。 echo
行将 somescript.sh
的 return 代码输出到 fd 3
。然后,3>&1
将保存的 return 代码发送到 $(...)
期望的 fd 1
。但是,这意味着旧的 fd 1
(来自 {somescript 2>&1 } | tee
)无处可去。所以旧的 fd 1
被重定向到 fd 4
和 >&4
(并且输入端被 4>&-
关闭,因为它不会被使用)。然后,一旦 $(...)
结束,末尾的 4>&1
会将 somescript|tee
的输出放回 fd 1
其他程序期望的位置。
哇!
如果没有 >&4
,由于 3>&1
,somescript.sh
的输出和 echo "$?"
的输出将在 fd 1
上混合。所以fd4
是在fd1
携带return代码的时候somescript.sh
的实际输出的握笔
如果您愿意使用命名管道,则可以免除所有文件描述符争论:
mkfifo p
tee -a somefile.txt < p &
. somescript.sh > p
rc=$?
在这里,我们 运行 tee
在后台,让它从命名管道 p
读取输入。该作业启动后,我们获取脚本并将其输出重定向到命名管道。脚本完成后,您可以使用普通赋值语句将其退出状态保存到 rc
。这也将关闭管道的外壳端,这将导致另一端也关闭并允许 tee
退出。