美文网首页
/dev/null 2>&1

/dev/null 2>&1

作者: 阿栋oxo | 来源:发表于2018-10-09 14:18 被阅读0次

    解析:

    /dev/null:代表空设备文件
    > :代表重定向到哪里,例如:echo "123" > /home/123.txt
    1 :表示stdout标准输出,系统默认值是1,所以">"等同于"1>"
    2 :表示stderr标准错误&
    & :表示等同于的意思,2>&1,表示2的输出重定向等同于1
    在shell中,每个进程都和三个系统文件 相关联:标准输入stdin,标准输出stdout、标准错误stderr,三个系统文件的文件描述符分别为0,1、2。

    command > /dev/null 2>&1 语句含义:

    > /dev/null : 表示标准输出重定向到空设备文件
    2> &1 :标准错误输出重定向(等同于)标准输出
    总的来说就是:将标准输出stdin重定向到/dev/null文件,即输出内容不打印到屏幕上,而是输出到/dev/null文件中。 2>&1 是将标准出错重定向到标准输出,这里的标准输出已经重定向到了/dev/null文件,即将标准出错也输出到/dev/null文件中。即 >/dev/null 2>&1 相当于 1>/dev/null 2>/dev/null ,不过两者也存在区别

    两者的区别:

    • command >file 2>file:stdout和stderr都直接送往文件 a ,a文件会被打开两遍,由此导致stdout和stderr互相覆盖。
    • command >file 2>&1 :stdout直接送往文件a ,stderr是继承了FD1的管道之后,再被送往文件a 。a文件只被打开一遍,就是FD1将其打开。
    • command >file 2>file相当于使用了FD1、FD2两个互相竞争使用文件 a 的管道;
    • command>filel 2>&1 只使用了一个管道FD1,但已经包括了stdout和stderr。
      从IO效率上来讲,command >a 2>&1的效率更高。

    下面通过一个例子来展示2>&1的效果:

    $ cat test.sh
    t
    date

    test.sh脚本中包含两个命令:
    1、(t)是一个不存在的命令,执行会报错,默认情况下,错误会输出到stderr。
    2、(date)则能正确执行,并且输出时间信息,默认输出到stdout

    $sh test.sh > test1.log
    ./test.sh: line 1: t: command not found
    $ cat test1.log
    Wed Jul 10 21:12:02 CST 2013

    (date)的执行结果被重定向到test1.log文件中,而(t)无法执行的命令错误则只打印在屏幕上。

    $ sh test.sh > test2.log 2>&1
    $ cat test2.log
    ./test.sh: line 1: t: command not found
    Tue Oct 9 20:53:44 CST 2007

    (date)和(t)的执行结果都被重定向到test2.log文件中。

    试想一下1与&1代表什么?

      2>1
         2>代表标准错误重定向,1代表将标准错误重定向到一个文件1,而不代表标准输出;
      2>&1
         2>代表标准错误重定向,&1就代表标准输出stdout了,就变成将标准错误重定向到标准输出。
      测试:
             ls xx >out.txt 2>1测试,没有xx这个文件的标准错误输出到了文件1中,out.txt文件是空的;假如文件1和out.txt不存在,系统会自动创建;
    
    stderr输出到文件1.png
             ls xx >out1.txt 2>&1测试,没有文件1生成,没有xx这个标准错误输出在out1.txt文件中;
    
    stderr输出到文件out1.txt.png

    为何2>&1要写在后面?

     command > file 2>&1 
        首先是command > file将标准输出重定向到file中, 2>&1 是标准错误拷贝了标准输出的行为,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中。 
     command 2>&1 >file 
       2>&1 标准错误拷贝了标准输出的行为,但此时标准输出还是在终端。>file 后输出才被重定向到file,但标准错误仍然保持在终端。
    

    用strace可以看到:

    1. command > file 2>&1
      这个命令中实现重定向的关键系统调用序列是:
      open(file) == 3
      dup2(3,1)
      dup2(1,2)
    1. command 2>&1 >file
      这个命令中实现重定向的关键系统调用序列是:
      dup2(1,2)
      open(file) == 3
      dup2(3,1)

    可以考虑一下不同的dup2()调用序列会产生怎样的文件共享结构。参考APUE 3.10, 3.12

    相关文章

      网友评论

          本文标题:/dev/null 2>&1

          本文链接:https://www.haomeiwen.com/subject/ptaboftx.html