zoukankan      html  css  js  c++  java
  • Shell重定向与exec

    前言

      首先我们需要知道exec是什么,exec是linux下面一个创建进程的方法,详情请参考:https://www.cnblogs.com/guge-94/p/11016176.html

    重定向

    概念

    • I/O重定向通常与FD有关
    • 三个常用FD(默认与keyboard、monitor、monitor有关)
    • 一般情况下,操作系统默认只存在这三个fd,但是我们通过ls去查看的时候发现会有一个大于2的fd,这是因为我们在查看的时候会有一个句柄产生,这个时候会生成一个新的fd
    FD说明
    0 stdin,标准输入
    1 stdout,标准输出
    2 stderr,标准错误输出

    查看文件描述符

    ll /proc/$$/fd

    重定向输出

    &- 关闭标准输出
    n&- 表示将 n 号输出关闭
    述所有形式都可以前导一个数字,此时建立的文件描述符由这个数字指定而不是缺省的 01。如:
    
    
    ... 2>file 运行一个命令并把错误输出(文件描述符 2)定向到 file。
    ... 2>&1 运行一个命令并把它的标准输出和输出合并。(严格的说是通过复制文件描述符 1 来建立文件描述符 2 ,但效果通常是合并了两个流。)
    我们对 2>&1详细说明一下 :
      2>&1 也就是 FD2=FD1 ,这里并不是说FD2 的值等于FD1的值,因为 > 是改变送出的数据信道,也就是说把 FD2 的 “数据输出通道” 改为 FD1 的 “数据输出通道”。
      如果仅仅这样,这个改变好像没有什么作用,因为 FD2 的默认输出和 FD1 的默认输出本来都是 monitor,一样的!但是,当 FD1 是其他文件,甚至是其他 FD 时,这个就具有特殊的用途了。请大家务必理解这一点。

    重定向恢复

    如果 stdin, stdout, stderr 进行了重定向或关闭, 但没有保存原来的 FD, 可以将其恢复到 default 状态吗?

    如果关闭了stdin,因为会导致退出,那肯定不能恢复。

    如果重定向或关闭 stdout和stderr其中之一,可以恢复,因为他们默认均是送往monitor(但不知会否有其他影响)。

    如果恢复重定向或关闭的 stdout: exec 1>&2 ,恢复重定向或关闭的stderr:exec 2>&1

    如果stdout和stderr全部都关闭了,又没有保存原来的FD,可以用:exec 1>/dev/tty 恢复。

    cmd >a 2>a 和 cmd >a 2>&1 为什么不同?

    • cmd >a 2>a :stdout和stderr都直接送往文件 a ,a文件会被打开两遍,由此导致stdout和stderr互相覆盖。
    • cmd >a 2>&1 :stdout直接送往文件a ,stderr是继承了FD1的管道之后,再被送往文件a 。a文件只被打开一遍,就是FD1将其打开。
    • 我想:他们的不同点在于:
    1. cmd >a 2>a 相当于使用了两个互相竞争使用文件a的管道;

    2. 而cmd >a 2>&1 只使用了一个管道,但在其源头已经包括了stdout和stderr。

    3. 从IO效率上来讲,cmd >a 2>&1的效率应该更高!

    常用命令语法

    exec 1>outfilename    # 打开文件outfilename作为stdout
    exec 2>errfilename    # 打开文件errfilename作为 stderr
    exec 1&-                   # 关闭 FD1
    exec 5>&-                # 关闭 FD5
     
    exec 4<&1              # 备份当前stdout至FD4
    exec 1>1.txt          # stdout重定向至1.txt
    exec 1<&4            # 恢复stdout
    exec 4>&-           # 关闭 FD4
    
    exec 6>&1       # 将标准输出与fd 6绑定
    exec 1>&6       # 将标准输出1恢复回来

    示例

    exec 1>&- 2>&-    # 关闭所有的输出

    重定向输入

    格式

    command-line [n]<file或文件描述符&设备

    将命令默认从键盘获得的输入,改成从文件,或者其它打开文件以及设备输入。执行这个命令,将标准输入0,与文件或设备绑定。将由它进行输入。

     

     

    示例

    实例一:用catfile文件里面的内容代替键盘输出,输出到屏幕。
    [root@asus-a53s data]# cp suc.test catfile
    [root@asus-a53s data]# cat < catfile 
    Ls                                    #这里如果内容过多,按下 [ctrl]+d 离开
    [root@asus-a53s data]# cat suc.test 
    ls
    
    实例二:从标准输入【键盘】获得数据,然后输出给catfile文件
    [root@asus-a53s data]# cat > catfile << EOF        #EOF可以是任何字符,代表结束
    > hello,This is my test!
    > EOF
    [root@asus-a53s data]# cat catfile               #上面用的是重定向覆盖,所以ls内容不见了
    hello,This is my test!
    
    实例三:从test.sh 获得输入数据,然后输出给文件catfile
    [root@asus-a53s data]# cat test.sh 
    1
    test1
    test1
    test1
    [root@asus-a53s data]# cat > catfile < test.sh     #这里在输入的时候不能用<<,因为<<同时是也代表结束输出
    [root@asus-a53s data]# cat catfile 
    1
    test1
    test1
    test1

    绑定重定向

    格式

    exec 文件描述符[n] <或> file或文件描述符或设备
    在上面讲的输入,输出重定向 将输入,输出绑定文件或设备后。只对当前那条指令是有效的。如果需要在绑定之后,接下来的所有命令都支持的话。就需要用exec命令

    示例

    实例一:学习exec的绑定使用
    [chengmo@centos5 shell]$ exec 6>&1
    #将标准输出与fd 6绑定
    
    [chengmo@centos5 shell]$ ls  /proc/self/fd/ 
    0  1  2  3  6
    #出现文件描述符6
    
    [chengmo@centos5 shell]$ exec 1>suc.txt
    #将接下来所有命令标准输出,绑定到suc.txt文件(输出到该文件)
    
    [chengmo@centos5 shell]$ ls -al
    #执行命令,发现什么都不返回了,因为标准输出已经输出到suc.txt文件了
     
    [chengmo@centos5 shell]$ exec 1>&6
    #恢复标准输出
    
    [chengmo@centos5 shell]$ exec 6>&-
    #关闭fd 6描述符
    
    [chengmo@centos5 ~]$ ls /proc/self/fd/
    1  2  3

    参考文档:

    http://xstarcd.github.io/wiki/shell/exec_redirect.html

    https://www.cnblogs.com/chengmo/archive/2010/10/20/1855805.html

  • 相关阅读:
    HDU 5105 Math Problem(BestCoder Round #18)
    HDU 5101 Select(BestCoder Round #17)
    HDU 5100 Chessboard(BestCoder Round #17)(找规律)
    HDU 5087 Revenge of LIS II(BestCoder Round #16)(次长上升子序列)
    HDU 5067 Harry And Dig Machine(BestCoder Round #14)
    HDU 5063 Operation the Sequence(BestCoder Round #13)
    2015ACM/ICPC亚洲区长春站-重现赛 1006 Almost Sorted Array
    2015ACM/ICPC亚洲区沈阳站-重现赛 1004 Pagodas
    Loadrunner 问题总结
    如何解决LodRunner中报错关于Error -10489
  • 原文地址:https://www.cnblogs.com/guge-94/p/11018082.html
Copyright © 2011-2022 走看看