linux重定向:在“> somfilename之前和之后使用“ 2>&1”之间的区别

时间:2019-03-02 15:16:50

标签: zsh

两者之间有什么区别

$ ls > dirlist 2>&1 

$ ls 2>&1 > dirlist

将stderr和stdout都重定向到目录。

2 个答案:

答案 0 :(得分:1)

Shell重定向/管道运算符按照在命令行上出现的顺序应用。一旦知道了这些信息并以正确的方式阅读了这些运算符,区别就会变得很明显,因此让我们更详细地看一下运算符:

    FD是文件描述符的缩写,是每个进程与文件(类似对象)关联的数字。文件描述符0到2具有特殊含义:它们是标准的输入/输出/错误流。如果您在外壳程序中运行的程序中没有任何重定向操作符,则它们实际上已连接到您的终端。
  • a重定向到b意味着:使a的FD与b引用相同的内容,即重定向后,两个文件描述符可以互换使用。 (旧的a已丢失)。在内部,这是通过dup2系统调用发生的。
  • >foo用写入stdout的句柄替换foo
  • 2>&1用一个句柄替换FD 2(stderr),该句柄写入FD 1(stdout)当时指的
  • >

请记住,这是两种变体的情况:

>foo 2>&1:shell打开一个新的FD,该FD写入foo,并将stdout重定向到它,这意味着FD 1现在写入foo。然后,将此FD 1复制到FD 2中,隐式关闭旧FD 2(它指的是原始stderr)。结果,两个FD都写入foo

2>&1 >foo:shell首先将FD 1复制到FD 2,以便将错误写入stdout。然后,它创建一个写入foo的新FD,并将其复制到FD 1中。由于重定向操作符的顺序,这将覆盖FD 1,但FD 2仍引用“旧的” FD1。结果,FD 2将写入旧的stdout(可能是您的终端),而FD 1将写入旧的foo的{​​{1}}。

答案 1 :(得分:0)

不确定zsh,但根据Bash manual

   Note  that  the order of redirections is significant.  For example, the
   command

          ls > dirlist 2>&1

   directs both standard output and standard error to  the  file  dirlist,
   while the command

          ls 2>&1 > dirlist

   directs  only the standard output to file dirlist, because the standard
   error was duplicated as standard output before the standard output  was
   redirected to dirlist.

对于ls > dirlist 2>&1,这就是发生的情况(在伪C代码中):

fd = open("dirlist");
dup2(fd, 1); // now stdout is a dup of fd so stdout points to "dirlist"
dup2(1, 2);  // now stderr becomes a dup of stdout so it also points to "dirlist"

对于ls 2>&1 > dirlist,会发生以下情况:

             // initially, both stdout and stderr point to the tty
dup2(1, 2);  // now stderr becomes a dup of stdout so they still point to the tty

fd = open("dirlist");
dup2(fd, 1); // now stdout is a dup of fd so stdout points to "dirlist",
             // but stderr still points to tty