zoukankan      html  css  js  c++  java
  • Shell命令中重定向与管道的概念

    # Shell命令中重定向与管道的概念
    
    在Linux系统管理中,Shell命令经常会使用重定向来定义命令的输入和输出。笔者在实现后台服务运行时,发现重定向的应用非常重要,所以总结了Shell中重定向的概念与应用。
    
    ## 0. 基本概念准备
    
    ### 0.0 Linux命令执行过程
    
    ![Shell命令执行过程](http://images.cnblogs.com/cnblogs_com/hongyanee/536427/o_shell_proc.jpg)
    
    对于任何一个Shell命令,都如上图的执行过程。首先从文件(Linux中,设备也是文件,一切都是文件)中读取标准输入;然后执行命令;如果执行成功则将标准输出定向到文件中,如果执行失败则标准错误定向到文件中。
    
    ### 0.1 文件描述符
    
    Linux为打开的文件而分配了文件描述符,通过对文件描述符的操作来操作文件。Linux系统本身会占用三个标准的文件描述符,0-2;而用户可以自定义的是3-ulimit,ulimit是可以自定义大小的数。
    
    Linux系统的3个标准文件描述符分别是:
    
    - 0  standard input. 标准输入,默认是键盘设备,也可以是一般文件。
    - 1  standard output. 标准输出,默认是监视器,也可以是一般文件。
    - 2  error output. 错误输出,默认是监视器。
    
    ### 0.2 重定向方向符号
    
    重定向的方向符号用大于符号(>)和小于符号(<)组合而成。意义分别如下:
    
    
    - < 输入符号。例如```command < input.file```的意义是将command的标准输入重定向为input.file。
    - > 输出符号。例如```command > output.file```的意义是将command的标准输出重定向为output.file。
    - >> 追加输出符号。例如```command >> output.file```的意义将command的标准输出以追加的方式重定向到output.file。
    
    上面例子中,```command > output.file```会覆盖output.file文件,而```command >> output.file```将输出追加到output.file中。
    
    ### 0.3 Shell中的&符号
    
    &符号在Shell中有两种比较常见的方式。
    
    - **当&符号在命令的最后时,作为后台执行命令的标记。**例如```command &```,command将在后台工作。
    - **当&符号后面跟数字时,&n表示文件描述符n代表的文件。**例如```command >&n```,表示将标准输出重定向到文件描述符n代表的文件中。
    
    - **当&符号后面跟-时,>&-表示关闭输出设备,<&-表示关闭输入设备。**。
    
    ## 1. 重定向的一般用法
    
    ### 1.0 输入重定向
    
    | 命令行 | 意义 |
    | ------ | ---- |
    | command < file.in | command命令以file.in作为标准输入 |
    
    ### 1.1 输出重定向
    
    | 命令行 | 意义 |
    | ------ | ---- |
    | command > file.out | 把标准输出重定向到文件file.out中 |
    | command >> file.out | 把标准输出以追加方式重定向到文件file.out中 |
    | command < file.in > file.out | 以file.in为输入,把标准输出重定向到文件file.out中 |
    | command 2 > file.err | 把标准错误重定向到文件file.err中 |
    | command 2 >> file.err | 把标准错误以追加方式重定向到文件file.err中 |
    | command > file.out 2>&1 | 把标准输出和错误一起重定向到文件file.out中 |
    | command >> file.out 2>&1 | 把标准输出和错误一起以追加方式重定向到文件file.out中 |
    
    ### 1.2 绑定重定向
    
    | 命令行 | 意义 |
    | ------ | ---- |
    | command >&m | 把标准输出重定向到文件描述符m中 |
    | command <&- | 关闭标准输入 | 
    | command 0>&- | 关闭输入设备 |
    | command << delimiter | 从标准输入中读入,直到遇见delimiter分界符 |
    
    ## 2. 重定向的特殊用法
    
    ### 2.0 重定向标准错误
    
    重定向到空设备,```command 2> /dev/null```,将标准错误输出到空设备。
    
    &符号表示文件:```command > file.out 2>&1```,将标准输出重定向到文件file.out,同时将标准错误重定向到文件标识符为1的文件中。由于文件标识符为1的文件正是标准输出,而标准输出已经重定向到文件file.out,因此上面这条命令会将标准输出和标准错误都重定向到文件file.out。
    
    ### 2.1 exec
    
    exec命令可以在新的shell环境中执行command命令。```exec command```,可以看成是启动了新的shell,在新的shell中执行command命令,实际上并没有。
    
    例子1:
    
    ```bash
    #!/bin/bash
    
    exec 3<&0 0test.sh; #打开test.sh可读写操作,与文件描述符3绑定
    
    while read line<&3
     do
        echo $line;  #循环读取文件描述符3(读取的是test.sh内容)
    done
    
    exec 3>&- #关闭文件的,输出绑定
    exec 3<&- #关闭文件的,输入绑定
    ```
    
    ## 3. Shell中管道(PIPE)的概念
    
    管道的命令操作符是'|',可以用来连接多个个命令。例如```command1 | command2 | command3```。管道的概念是将前一个命令的标准输入作为后一个命令的标准输出,如下图所示:
    
    ![Shell管道原理](http://images.cnblogs.com/cnblogs_com/hongyanee/536427/o_pipe.png)
    
    上述命令的执行过程是这样的:
    
    1. 首先执行command1,执行完成后标准输出并不输出,而是作为command2的标准输入;
    2. 将command1的标准输出作为command2的标准输入,执行command2,且将command2的标准输出作为command3的标准输入输入。
    3. 将command2的标准输出作为command3的标准输入,执行command3,输入command3的标准输出。
    
    **如果其中有命令执行错误会怎么样呢?**
    
    PIPE中命令串行执行,如果遇到错误,则继续执行。
    
    1. 如果command1运行失败,屏幕打印标准错误,然后继续运行```command2 | command3```。
    2. 如果command1执行成功并将标准输出作为command2的标准输入,然后执行command2。如果command2执行失败,屏幕打印command2的标准错误,并且继续执行command3。
    
    
    ## 参考:
    
    [Linux shell的标准输入、输出和错误](http://blog.csdn.net/cjfeii/article/details/10084343)
    
    [linux shell数据重定向(输入重定向与输出重定向)详细分析](http://www.cnblogs.com/chengmo/archive/2010/10/20/1855805.html)
    
    [linux命令后台运行](http://www.cnblogs.com/lwm-1988/archive/2011/08/20/2147299.html)
    
    [Shell管道命令(pipe)使用及与重定向区别](http://www.jb51.net/LINUXjishu/32565.html)
    
    
  • 相关阅读:
    nuxt实践
    安卓H5软键盘遮挡输入框
    h5复制粘贴板,打开APP功能
    MVC3
    MVC3
    C#高编
    接口的显式实现(转)
    E-Retail 框架学习
    C#高编
    实现DIV居中布局三种途径(转)
  • 原文地址:https://www.cnblogs.com/hongyanee/p/3445068.html
Copyright © 2011-2022 走看看