是否可以将两个以上的标准流连接到 Linux 中的一个终端?
Is it possible to connect more than the two standard streams to a terminal in Linux?
考虑以下简单程序,假设它位于名为 Test.c
.
的文件中
#include <stdio.h>
int main(){
fprintf(stdout, "Hello stdout\n");
fprintf(stderr, "Hello stderr\n");
}
假设我将这个程序编译成一个名为 Test
和 运行 的可执行文件,如下所示。
./Test > Out 2> Err
在此运行 之后,我将有两个文件Out
和Err
,它们将分别包含这两个消息。
这很棒,因为我通常可以将两种不同类型的消息打印到控制台,然后使用 bash 重定向过滤其中一种或两种。然而,我只能用两个文件描述符进行这种过滤这一事实似乎非常有限。
有什么方法可以打开第三个或第 n 个文件描述符,指向终端输出,以便我可以单独过滤它?
语法可能是这样的。
./Test > Out 2> Err 3> Err2
我推测 bash
可能对此有一些初步的支持,因为下面的测试似乎暗示 bash
会将 &
之后的数字视为一个文件描述符。
$ ./Test >&2
Hello stdout
Hello stderr
$ ./Test >&3
bash: 3: Bad file descriptor
在 shell、运行
exec 3>/dev/tty
...或...
exec 3>&1
...将打开文件描述符 3,将其明确指向您的 TTY(在第一种情况下),或指向 stdout 当前正在写入的位置(在第二种情况下)。
如果你想在程序中使用它,我强烈建议将一个 FD 号码作为一个可选参数来写入额外的日志:
yourprogram --extra-logs-fd=3
...将该输出与 stderr 组合,或者如果没有给出此类选项,则完全(视情况而定)将其抑制。 (想要将额外日志记录转到 stdout 的用户因此可以使用 --extra-logs-fd=1
,或 --extra-logs-fd=2
作为 stderr)。
更好的是,如果您的唯一目标 OS 是 Linux,则只需接受要写入的文件名:
# to write to a file
yourprogram --extra-logs=extra_logs.txt
# to write to FD 3
yourprogram --extra-logs=/dev/fd/3
# to write to a tee program, then to stderr (in ksh or bash)
yourprogram --extra-logs=>(tee extra_logs.txt >&2)
...当然,您 可以 使用 FD 模式完成所有操作(在第一种情况下,只需在 shell 中重定向 3>extra_logs.txt
,和3> >(tee extra_logs.txt >&2)
在第三个),但这让你手工完成管理FD号码的工作,有什么好处?
考虑以下简单程序,假设它位于名为 Test.c
.
#include <stdio.h>
int main(){
fprintf(stdout, "Hello stdout\n");
fprintf(stderr, "Hello stderr\n");
}
假设我将这个程序编译成一个名为 Test
和 运行 的可执行文件,如下所示。
./Test > Out 2> Err
在此运行 之后,我将有两个文件Out
和Err
,它们将分别包含这两个消息。
这很棒,因为我通常可以将两种不同类型的消息打印到控制台,然后使用 bash 重定向过滤其中一种或两种。然而,我只能用两个文件描述符进行这种过滤这一事实似乎非常有限。
有什么方法可以打开第三个或第 n 个文件描述符,指向终端输出,以便我可以单独过滤它?
语法可能是这样的。
./Test > Out 2> Err 3> Err2
我推测 bash
可能对此有一些初步的支持,因为下面的测试似乎暗示 bash
会将 &
之后的数字视为一个文件描述符。
$ ./Test >&2
Hello stdout
Hello stderr
$ ./Test >&3
bash: 3: Bad file descriptor
在 shell、运行
exec 3>/dev/tty
...或...
exec 3>&1
...将打开文件描述符 3,将其明确指向您的 TTY(在第一种情况下),或指向 stdout 当前正在写入的位置(在第二种情况下)。
如果你想在程序中使用它,我强烈建议将一个 FD 号码作为一个可选参数来写入额外的日志:
yourprogram --extra-logs-fd=3
...将该输出与 stderr 组合,或者如果没有给出此类选项,则完全(视情况而定)将其抑制。 (想要将额外日志记录转到 stdout 的用户因此可以使用 --extra-logs-fd=1
,或 --extra-logs-fd=2
作为 stderr)。
更好的是,如果您的唯一目标 OS 是 Linux,则只需接受要写入的文件名:
# to write to a file
yourprogram --extra-logs=extra_logs.txt
# to write to FD 3
yourprogram --extra-logs=/dev/fd/3
# to write to a tee program, then to stderr (in ksh or bash)
yourprogram --extra-logs=>(tee extra_logs.txt >&2)
...当然,您 可以 使用 FD 模式完成所有操作(在第一种情况下,只需在 shell 中重定向 3>extra_logs.txt
,和3> >(tee extra_logs.txt >&2)
在第三个),但这让你手工完成管理FD号码的工作,有什么好处?