如何解决是否可以将文件描述符3重定向到变量?
function f()
{
echo "normal message" >&1
echo "error message" >&2
echo "special message" >&3
}
是否可以以完全不重定向stdout和stderr并且文件描述符3的输出存储在变量中的方式调用f
?我知道使用临时文件是可能的:
f 3> /tmp/file
variable=$(cat /tmp/file)
但是没有临时文件是否有可能?
解决方法
是否可以以完全不重定向stdout和stderr且文件描述符3的输出存储在变量中的方式来调用f?
不。您不能将文件描述符重定向到变量,因为这样一来,变量内容将不得不在另一个进程执行过程中同时修改为当前shell正在执行的操作。就是您可以使用另一个进程来执行此操作,该进程将从文件描述符读取的数据流式传输到该进程与Shell之间的某个共享内存中,然后Shell在扩展变量时读取该共享内存内容。我相信您可以修补bash
来支持这种设置。
但是还是要执行一个函数,而不是对>&3
进行硬编码:
log() {
variable+="$("$@")"$'\n'
}
log echo "special message"
或者更好(或更糟),如果您打算在当前shell中而不是在子shell中执行该过程:
log() {
logtmpfile=$(tmpfile)
"$@" > "$logtmpfile"
variable+="$(<"$logtmpfile")"$'\n'
rm "$logtmpfile"
}
但是没有临时文件是否有可能?
最好不要。文件是异步进程之间同步的最简单方法。 (有一种hacky-hacky方法,该方法取决于管道exec 3<> >(sleep infinity); echo 123 >&3; timeout 0.1 cat <&3
中的缓冲,但是它将以意外的方式失败/阻止。)
我刚发现以下语法:
{ variable=$(f 4>&1 1>&3 3>&4); } 3>&1
似乎可以得到我想要的结果。
当然,我的提问方式是:“以完全不重定向stdout和stderr的方式”在这里不适用,但我真正想要的只是在单独的文件描述符上的stdout和stderr。因此,我会将KamilCuk的答案保留为接受状态,但我想将其发布在此处,以防其他人需要。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。