是否可以将文件描述符 3 重定向到一个变量?
Is it possible to redirect file descriptor 3 to a variable?
function f()
{
echo "normal message" >&1
echo "error message" >&2
echo "special message" >&3
}
是否可以这样调用 f
,使 stdout 和 stderr 根本不被重定向,并且文件描述符 3 的输出存储在一个变量中?我知道使用临时文件是可能的:
f 3> /tmp/file
variable=$(cat /tmp/file)
但是没有临时文件可以吗?
Is it possible to call f in such a way that stdout and stderr are not redirected at all and output of file descriptor 3 is stored in a variable?
没有。您不能将文件描述符重定向到变量,因为变量内容必须在另一个进程执行过程中被修改,与当前 shell 正在执行的操作同时进行。 IE。您可以使用另一个进程来完成此操作,该进程将从文件描述符读取的数据流式传输到该进程与 shell 之间的某个共享内存中,然后 shell 将在扩展变量时读取该共享内存内容。我相信你可以修补 bash
来支持这样的设置。
但是还是做一个函数而不是硬编码>&3
:
log() {
variable+="$("$@")"$'\n'
}
log echo "special message"
或更好(或更糟)如果您打算在当前 shell 中执行进程,而不是在子shell 中执行进程:
log() {
logtmpfile=$(tmpfile)
"$@" > "$logtmpfile"
variable+="$(<"$logtmpfile")"$'\n'
rm "$logtmpfile"
}
But is it possible without a temp file?
最好不要。文件是在异步进程之间进行同步的最简单方式。 (有一种 hacky-hacky 方法依赖于管道中的缓冲 exec 3<> >(sleep infinity); echo 123 >&3; timeout 0.1 cat <&3
但它会 fail/block 以意想不到的方式。
我刚找到这个语法:
{ variable=$(f 4>&1 1>&3 3>&4); } 3>&1
这似乎得到了我想要的结果。
当然,我表达问题的方式:“以这样一种方式,即 stdout 和 stderr 根本不被重定向”在这里并不适用,但我真正想要的只是单独文件描述符上的 stdout 和 stderr。出于这个原因,我将保留 KamilCuk 的答案,但我想 post 在这里以防其他人需要它。
function f()
{
echo "normal message" >&1
echo "error message" >&2
echo "special message" >&3
}
是否可以这样调用 f
,使 stdout 和 stderr 根本不被重定向,并且文件描述符 3 的输出存储在一个变量中?我知道使用临时文件是可能的:
f 3> /tmp/file
variable=$(cat /tmp/file)
但是没有临时文件可以吗?
Is it possible to call f in such a way that stdout and stderr are not redirected at all and output of file descriptor 3 is stored in a variable?
没有。您不能将文件描述符重定向到变量,因为变量内容必须在另一个进程执行过程中被修改,与当前 shell 正在执行的操作同时进行。 IE。您可以使用另一个进程来完成此操作,该进程将从文件描述符读取的数据流式传输到该进程与 shell 之间的某个共享内存中,然后 shell 将在扩展变量时读取该共享内存内容。我相信你可以修补 bash
来支持这样的设置。
但是还是做一个函数而不是硬编码>&3
:
log() {
variable+="$("$@")"$'\n'
}
log echo "special message"
或更好(或更糟)如果您打算在当前 shell 中执行进程,而不是在子shell 中执行进程:
log() {
logtmpfile=$(tmpfile)
"$@" > "$logtmpfile"
variable+="$(<"$logtmpfile")"$'\n'
rm "$logtmpfile"
}
But is it possible without a temp file?
最好不要。文件是在异步进程之间进行同步的最简单方式。 (有一种 hacky-hacky 方法依赖于管道中的缓冲 exec 3<> >(sleep infinity); echo 123 >&3; timeout 0.1 cat <&3
但它会 fail/block 以意想不到的方式。
我刚找到这个语法:
{ variable=$(f 4>&1 1>&3 3>&4); } 3>&1
这似乎得到了我想要的结果。
当然,我表达问题的方式:“以这样一种方式,即 stdout 和 stderr 根本不被重定向”在这里并不适用,但我真正想要的只是单独文件描述符上的 stdout 和 stderr。出于这个原因,我将保留 KamilCuk 的答案,但我想 post 在这里以防其他人需要它。