&> 重定向是如何在 UNIX shell 中实现的?
How is &> redirection implemented in UNIX shells?
我们知道 &> outfile
在 UNIX shell 中将 stdout
和 stderr
重定向到 outfile
。但是 shell 是如何实现的呢?我写了一个简单的测试:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int fd = open("tmpf", O_CREAT | O_TRUNC | O_WRONLY, 0644);
// redirect stdout to file
dup2(fd, 1);
close(fd);
// redirect stderr to stdout
dup2(2, 1);
close(2);
// print stuff to file
fprintf(stdout, "stdout string\n");
fprintf(stderr, "stderr string\n");
}
它只是将 stdout
重定向到文件,然后将 stderr
重定向到 stdout
。但这不起作用。上面的代码产生
$ ./a.out
stdout string
$ cat tmpf
$
如果我们交换stdout->file
和stderr->stdout
的顺序,它会给出以下结果
$ ./a.out
$ cat tmpf
stdout string
$
不要关闭目标 FD。您应该关闭的唯一 FD 是 tmpf
上的句柄; stdout 和 stderr 都需要打开才能写入它们。
此外,将 stdout 复制到 stderr 应该是 dup2(1,2)
-- 将 stderr 复制到 stdout(如原始代码所做的那样)会丢弃 tmpf
上的句柄。
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int fd = open("tmpf", O_CREAT | O_TRUNC | O_WRONLY, 0644);
// copy FD to stdout ("redirect stdout to fd")
dup2(fd, 1);
// fd was copied to stdout so we don't need the original
close(fd);
// copy stdout fd to stderr ("redirect stdout to stderr")
dup2(1, 2);
// print stuff to file
fprintf(stdout, "stdout string\n");
fprintf(stderr, "stderr string\n");
}
还可以在 https://replit.com/@CharlesDuffy2/KnowingWobblyFibonacci#main.c 的在线沙箱中查看此 运行(您可以使用“显示文件”在输出中查看生成的 tmpf
文件)。
我们知道 &> outfile
在 UNIX shell 中将 stdout
和 stderr
重定向到 outfile
。但是 shell 是如何实现的呢?我写了一个简单的测试:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int fd = open("tmpf", O_CREAT | O_TRUNC | O_WRONLY, 0644);
// redirect stdout to file
dup2(fd, 1);
close(fd);
// redirect stderr to stdout
dup2(2, 1);
close(2);
// print stuff to file
fprintf(stdout, "stdout string\n");
fprintf(stderr, "stderr string\n");
}
它只是将 stdout
重定向到文件,然后将 stderr
重定向到 stdout
。但这不起作用。上面的代码产生
$ ./a.out
stdout string
$ cat tmpf
$
如果我们交换stdout->file
和stderr->stdout
的顺序,它会给出以下结果
$ ./a.out
$ cat tmpf
stdout string
$
不要关闭目标 FD。您应该关闭的唯一 FD 是 tmpf
上的句柄; stdout 和 stderr 都需要打开才能写入它们。
此外,将 stdout 复制到 stderr 应该是 dup2(1,2)
-- 将 stderr 复制到 stdout(如原始代码所做的那样)会丢弃 tmpf
上的句柄。
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int fd = open("tmpf", O_CREAT | O_TRUNC | O_WRONLY, 0644);
// copy FD to stdout ("redirect stdout to fd")
dup2(fd, 1);
// fd was copied to stdout so we don't need the original
close(fd);
// copy stdout fd to stderr ("redirect stdout to stderr")
dup2(1, 2);
// print stuff to file
fprintf(stdout, "stdout string\n");
fprintf(stderr, "stderr string\n");
}
还可以在 https://replit.com/@CharlesDuffy2/KnowingWobblyFibonacci#main.c 的在线沙箱中查看此 运行(您可以使用“显示文件”在输出中查看生成的 tmpf
文件)。