Linux重定向:从一句代码加深理解



  • 1 重定向迷思:

       touch test.txt
       echo hello > test.txt
       (cat; echo apple > /dev/stdin; cat) < test.txt
    

    以上命令执行完毕后,标准输出流会输出hello,而没有apple,为什么呢?
    这个要从重定向的机制开始理解。Linux系统是以文件系统为核心理念的系统,即"一切都是文件"。而流也不例外,比如标准流有stdinstdoutstderr。这三者均有file descriptor分别为0、1、2。而它们对应的文件均在/dev目录下,分别为/dev/stdin/dev/stdout/dev/stderr
    重定向的本质是将某个file descriptor所操作的文件修改为命令中提供的文件。例如:

        ls -alF 2>/dev/null
    

    就是将标准错误流stderr所写入的文件改为/dev/null
    那么回到一开始的问题,为什么标准输出流只输出hello呢?
    在执行cat的时候,标准输入流就已经指向了test.txt,因此直接从标准输入流中读入内容,即为hello
    但是,要注意到一个细节,和C语言一样,文件的读写是有位置的,即file position,经过第一个指令后,标准输入流的file descriptor已经读了6个字节了,即"hello"以及一个echo默认自带的换行符。此时,echo将字符串"apple"覆盖到/dev/stdin中,但由于已经读了6个字符了,此时文件位置指向"apple"尾部的EOF
    最后再执行cat,读取/dev/stdin的最后一个字符——EOF,该字符在cat下不会打印任何字符,只是终止cat

    2 重定向的语法:

    一般来说,重定向有两种语法:为file descriptor打开一个新的文件,或者将某个file descriptor修改为与另一个同类型修饰符操作同一个文件,简称复制修饰符(Duplicate Descriptor)

    1. [n] > file:为修饰符n打开一个文件供其写入。若不给出n则默认为标准输出流
      [n] < file: 为修饰符打开一个文件供其读取。若不给出n则默认为标准输入流
    2. [n] >& m: 将修饰符n设置为与m操作对象一致。默认为标准输出流。
      [n] <& m: 默认为标准输入流。

 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待