考虑下面的简单程序,假设它在一个名为Test.c
的文件中。
#include <stdio.h> int main(){ fprintf(stdout, "Hello stdout\n"); fprintf(stderr, "Hello stderr\n"); }
假设我将这个程序编译成名为Test
的可执行文件并按如下所示运行它。
./Test > Out 2> Err
运行后,我将有两个文件Out
和Err
,它们分别包含两条消息。
这非常棒,因为我可以将两种不同types的消息通常打印到控制台,然后使用bashredirect过滤一个或两个消息。 但是,我只能用两个文件描述符进行这种过滤的事实似乎非常有限。
有没有办法打开指向terminal输出的第三个或第n个文件描述符,所以我可以单独过滤它?
语法可能是这样的。
./Test > Out 2> Err 3> Err2
我推测bash
可能有一些基本的支持,因为下面的testing,这似乎暗示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相结合,或者如果没有给出这样的选项,则将其完全抑制(如适用)。 (想要额外记录到标准输出的用户因此可以使用--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>extra_logs.txt
情况下3> >(tee extra_logs.txt >&2)
),但是这个让你手工管理FD号码,有什么优势?