重定向的一些注意事项{"2>&1 > file"和 "> file 2>&1"区别}


什么是文件描述符?
文件描述符是一个简单的正整数,用以标明每一个被进程所打开的文件和socket。
最前面的三个文件描述符(0,1,2)分别与标准输入(stdin),标准输出(stdout)和标准错误(stderr)对应。
“2>&1 > file”和 “> file 2>&1″区别?
1.php test.php 2>&1 > file :错误输出到终端标准输出被重定向到文件file(看来还是有个先后顺序!)效果其实和(php test.php > file)一样,因为标准错误默认也是输出到终端的。
2.php test.php > file 2>&1 :标准输出被重定向到文件file,然后错误输出也重定向到和标准输出一样,所以错误也输出到文件file。(先将标准输出重定向到文件file,然后错误输出重定向到标准输出,所以所有的输出都将被重定向到文件file
stderr_stdout_2
综上可知,如果希望能将一个脚本or命令的标准输出、执行时的错误输出都保存下来(重定向至某一文件),则需要使用第二种方式,即:先声明重定向至文件file,然后将错误输出也重定向到标准输出,从而将所有可能的输出均重定向至文件file。(一般最好用tee命令,既可以重定向,又可以实时查看,但需要占用一个屏幕)
参考文章:

《 “重定向的一些注意事项{"2>&1 > file"和 "> file 2>&1"区别}” 》 有 5 条评论

  1. `
    $ find /etc -name passwd > /dev/null #相当于只看报错信息
    $ find /etc -name passwd 2> /dev/null #相当于只看正确输出信息
    $ find /etc -name passwd &> /dev/null #所有输出都不看,也可以写成「>&」

    $ find /etc -name passwd 2>&1 #打印正确+错误输出信息

    #打开3号和4号描述符作为输出和错误输出,并且分别关联文件
    exec 3> /tmp/stdout
    exec 4> /tmp/stderr

    #将标准输入关联到3号描述符,关闭原来的1号fd
    exec 1>&3-
    #将标准报错关联到4号描述符,关闭原来的2号fd
    exec 2>&4-

    #这个find命令的所有正常输出都会写到/tmp/stdout文件中,错误输出都会写到/tmp/stderr文件中
    find /etc/ -name “passwd”

    #关闭两个描述符
    exec 3>&-
    exec 4>&-

    #一般输入输出重定向都是放到命令后面作为后缀使用,所以如果单纯改变脚本的描述符,需要在前面加exec命令。这种用法也叫做描述符魔术。
    `
    更多参考链接:
    http://liwei.life/2016/06/06/shell%E7%BC%96%E7%A8%8B%E4%B9%8B%E7%89%B9%E6%AE%8A%E7%AC%A6%E5%8F%B7/

  2. stdout 和 stderr 两个流的区别是啥?
    https://www.v2ex.com/t/847794
    `
    q:一直以来日志都是输出到 stdout 流的,不过最近看了一些项目好像都是输出到 stderr ,搞不太懂为什么要这么做,有大佬来讲一下两个的区别吗?

    answer(s):
    分开两个可以实现 stdout 输出数据,stderr 输出错误信息,互不干扰。
    一些语言提供的 IO 库封装有缓冲功能,可能会对 stdout 和 stderr 使用不同的缓冲设置

    因为你可能需要将 stdout 通过管道传递给下一个进程,而 stderr 此时就可以拿来显示命令执行状态 /日志

    日志输出到 stderr 更符合 POSIX 规范
    At program start-up, three streams shall be predefined and need not be opened explicitly:
    standard input (for reading conventional input),
    standard output (for writing conventional output),
    and standard error (for writing diagnostic output).

    When opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.
    `
    https://zh.wikipedia.org/wiki/%E6%A8%99%E6%BA%96%E4%B8%B2%E6%B5%81
    https://pubs.opengroup.org/onlinepubs/9699919799/functions/stderr.html

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注