我了解到我们有两种方法将 stdout 和 stderr 重定向到同一文件。第一种方法是:
ls -l /bin > ls-output.txt 2>&1
作为作者这本书状态:使用此方法,我们执行 2 次重定向,首先将 stdout 重定向到 ls-output.txt,然后将 stderr(文件描述符 2)重定向到 stdout(使用文件描述符 1)。
重定向的顺序很重要。
ls -l /bin 2>&1 >ls-output.txt
会将 stderr 重定向到屏幕。
我的问题是:像许多编程语言一样,命令的设计是否考虑到了一些关联性和优先级规则和我们如何在屏幕上书写命令的同时读取命令?和后台执行命令的顺序是怎样的?
以下是我对执行顺序的看法:首先,命令ls -l /bin
将其输出发送到 stdout,并将错误发送到 stderr(其中任何一个)。然后,stderr 被重定向到 stdout。(如果有任何错误,例如:如果ls -l /binn
使用)现在,stdout 流包含两者之一(输出或错误),然后将其重定向到文件ls-输出.txt
答案1
重定向是从左到右处理的。当你执行:
ls -l /bin >ls-output.txt 2>&1
shell 在内部大约执行以下操作:
fork(); // Then in the child process:
fd = open("ls-output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2(fd, 1);
close(fd);
// 2>&1
dup2(1, 2);
然后它ls -l /bin
使用这些描述符附件执行命令。由于您stdout
首先重定向到该文件,因此 的重定向stderr
将继承该重定向。
如果你要写
ls -l /bin 2>&1 >ls-output.txt
操作顺序将颠倒过来:
// 2>&1
dup2(1, 2);
// >ls-output.txt
fd = open("ls-output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2(fd, 1);
close(fd);
这连接stderr
到原来的stdout
,这可能是终端。然后它重定向stdout
到一个文件;这对 没有影响stderr
。