V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
autumn2018
V2EX  ›  程序员

好像今天才看明白 Linux 的重定向语法.

  •  
  •   autumn2018 · 2018-11-29 18:39:06 +08:00 · 1569 次点击
    这是一个创建于 2171 天前的主题,其中的信息可能已经有所发展或是发生改变。
    以 bash 文档里的一个例子来说:
    ls > dirlist 2>&1
    以前一直疑惑为什么 2 前面不加&号,写成&2>&1 .
    刚看了一些资料,原来 2>连起来是一个操作符(token),这个操作符由 2 和>组成.它的名字就叫做 2>, 这个操作符的功能是"把 stderr 重定位到"....哈哈,算是一种"内含操作数的操作符".
    另外两个操作符是:
    0>
    1>
    其中 1>的 1 可以省略,就成了我们日常看到的>号.是省略来的,linux 并没有一个所谓的"重定向符号" > . 
    挺误导人的吧.好多教程里都没提到这个省略,导致我长期都看不懂.上面命令是这样断句的:
    ls
    1> dirlist
    2> &1
    其中&1 里面的&是打标记,表明后面的 1 是 fd 号,不是文件.

    再一个问题是,叫做"重定向"其实不好,>号的功能更接近"指针转指",或者说"指针赋值".
    像比上面的 2> &1,它实际的功能是:
    让"2 号 fd"指向"1 号 fd"所指的内核里的 file descriptor object .
    这类似于 java 里的改变引用对象:
    s1 = s2
    s1 被指到 s2 所指的 object .
    或者类似于 C 语言里的指针赋值:
    p1 = p2

    2> &1 前面的 1> dirlist 这句,已经把"1 号 fd"转指到 dirlist 这个文件的 descriptor object 了.即,"1 号 fd"引用的已经不是 stdout 这个文件了.
    所以 2> &1 最终的效果是,把 stderr 也重定位到 dirlist 文件上去.

    但对新手来说,2> &1 的直观感觉,就是"把本该输出到 stderr 的内容重定向到 stdout 上去",对吧.你都说了是"重定向"了.

    如果叫做"指针修改符",用户反而会警觉,心里念叨着 1 现在指着哪儿.而且他们会注意到,2>这个操作符,操作对象并不是"本该输出到 stderr 的内容",而是"原本引用着 stderr 文件的 2 号 fd",是在操控它的指向.

    搜帖子的时候,看到 csdn 上的一篇文章,令我倍感欣慰:
    https://blog.csdn.net/niu91/article/details/79869505?utm_source=blogxgwz3

    大家看他文章的第一段就行了,我感觉到他的思路跟这几年的我一模一样. 而且他挺厉害的了,理解错了,还能把语法写对,我之前好像连语法都凑不出来
    sbw
        1
    sbw  
       2018-11-29 18:57:46 +08:00
    >& 才是一起的吧,POSIX file descriptor 0 为 stdin 1 为 stdout 2 为 stderr
    autumn2018
        2
    autumn2018  
    OP
       2018-11-29 19:32:51 +08:00
    @sbw
    谢谢回复.用空格实验了一下(下面用下划线表示空格,怕看不清).
    ls > dirlist 2>&1  改成:
    ls > dirlist 2>&_1  回车正常
    ls > dirlist 2> _&1  回车运行出错:bash: syntax error near unexpected token `&'
    看来&确实跟>是绑在一起的.

    但改成 ls > dirlist 2_>& 1   也出错  ls: cannot access '2': No such file or directory
    那应该就是:2>&这三个字符是绑在一起的.
    sbw
        3
    sbw  
       2018-11-29 20:04:05 +08:00
    @autumn2018 > 要和前面的字符连起来是因为不连起来的话没法区分前面的 2 是参数还是指的描述符。
    根据语法 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_06
    >& 是一个操作符
    lance6716
        4
    lance6716  
       2018-11-29 20:41:51 +08:00 via Android
    bash 这种工具看文档就好了啊…怎么还瞎想…
    https://www.gnu.org/software/bash/manual/html_node/Redirections.html
    autumn2018
        5
    autumn2018  
    OP
       2018-11-29 22:02:23 +08:00
    @sbw 多谢链接.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1335 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 834ms · UTC 17:50 · PVG 01:50 · LAX 09:50 · JFK 12:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.