是否可以将超过两个标准流连接到Linux中的终端?

时间:2015-03-06 23:25:03

标签: c linux bash shell command-line

考虑以下简单程序,并假设它位于名为Test.c的文件中。

#include <stdio.h>

int main(){
    fprintf(stdout, "Hello stdout\n");
    fprintf(stderr, "Hello stderr\n");
}

假设我将此程序编译为名为Test的可执行文件并按如下方式运行。

./Test > Out 2> Err

在此次运行之后,我将有两个文件OutErr,它们将分别包含两个消息。

这很棒,因为我可以通常在控制台上打印两种不同类型的消息,然后使用bash重定向过滤一个或两个。但是,我只能用两个文件描述符进行这种过滤的事实似乎非常有限。

有没有办法打开指向终端输出的第三个或第n个文件描述符,所以我可以单独过滤它?

语法可能是这样的。

./Test > Out 2> Err 3> Err2

我推测bash可能会对此有一些基本的支持,因为以下测试似乎暗示bash会将&之后的数字视为文件描述符。

$ ./Test >&2
Hello stdout
Hello stderr
$ ./Test >&3
bash: 3: Bad file descriptor

1 个答案:

答案 0 :(得分:4)

在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。

更好的是,如果您的唯一目标操作系统是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号码的工作,有什么好处?

相关问题