zoukankan      html  css  js  c++  java
  • 【转】linux shell I/O重定向小结

    转自:http://molinux.blog.51cto.com/2536040/469554

    材料总结,大部分内容及示例摘自《Advanced Bash-Scripting Guide》中chapt:An in-depth exploration of the art of shell scripting;需要详细请自行参看。

           对于重定向简单的解释就是捕捉一个文件, 命令, 程序, 脚本, 或者甚至是脚本中的代码块的输出, 然后将这些输出作为输入发送到另一个文件, 命令, 程序, 或脚本中.

          默认情况下始终有3个"文件"处于打开状态, stdin (键盘), stdout (屏幕), andstderr (错误消息输出到屏幕上).

          每个打开的文件都会被分配一个文件描述符.stdinstdout, 和stderr的文件描述符分别是0, 1, 和 2. 对于正在打开的额外文件, 保留了描述符3到9. 在某些时候将这些格外的文件描述符分配给stdin, stdout, 或者是stderr作为临时的副本链接是非常有用。并且在经过复杂的重定向和刷新之后需要把它们恢复成正常的样子 

    文件描述符:

    表示范围:  0-9

    0-2:是系统定义好的。

             0:代表STDIN,标准输入

             1:代表STDOUT,是标准输出

              2:代表STDERR,是标准错误输出

    3-9:系统未定义,需要使用的可以自己定义使用

    1. COMMAND_OUTPUT > 
    2.       # 重定向stdout到一个文件. 
    3.       # 如果没有这个文件就创建, 否则就覆盖. 
    4.  
    5.    COMMAND_OUTPUT >> 
    6.      # 重定向stdout到一个文件. 
    7.       # 如果文件不存在, 那么就创建它, 如果存在, 那么就追加到文件后边. 
    8.  
    9.  
    10.       # 单行重定向命令(只会影响它们所在的行): 
    11.     
    12.  #==========================================================
    13.    1>filename 
    14.       # 重定向stdout到文件"filename". 
    15.    1>>filename 
    16.       # 重定向并追加stdout到文件"filename". 
    17.    2>filename 
    18.       # 重定向stderr到文件"filename". 
    19.    2>>filename 
    20.       # 重定向并追加stderr到文件"filename". 
    21.    &>filename 
    22.       # 将stdout和stderr都重定向到文件"filename"
    23. #============================================================
    24.   2>&1
        # 重定向stderr到stdout.
        # 得到的错误消息与stdout一样, 发送到一个地方.

        i>&j
      # 重定向文件描述符ij.
        # 指向i文件的所有输出都发送到j中去.

        >&j
        # 默认的, 重定向文件描述符1(stdout)到 j.
        # 所有传递到stdout的输出都送到j中去.

        0< FILENAME
        < FILENAME

        # 从文件中接受输入.
        # 与">"是成对命令, 并且通常都是结合使用.
        #
        # grep search-word <filename
       
       
        [j]<>filename
        # 为了读写"filename", 把文件"filename"打开, 并且分配文件描述符"j"给它.
        # 如果文件"filename"不存在, 那么就创建它.
        # 如果文件描述符"j"没指定, 那默认是fd 0, stdin.
        #
        # 这种应用通常是为了写到一个文件中指定的地方.
    25. 例:
        echo 1234567890 > File # 写字符串到"File".
        exec 3<> File # 打开"File"并且给它分配fd 3.
        read -n 4 <&3 # 只读4个字符.
        echo -n . >&3 # 写一个小数点.
        exec 3>&- # 关闭fd 3.
        cat File # ==> 1234.67890
        # 随机存储.

    可以将输入输出重定向的多个实例书写到一行命令中

             #command < input-file > output-file

    可以将多个输出流重定向到一个文件上:

    1 ls -yz >> command.log 2>&1
        #  将错误选项"yz"的结果放到文件"command.log"中.
        #  因为stderr被重定向到这个文件中,
        #+ 所有的错误消息也就都指向那里了.
        
        #  注意, 下边这个例子就不会给出相同的结果.
        ls -yz 2>&1 >> command.log
        #  输出一个错误消息, 但是并不写到文件中.
        
        #  如果将stdout和stderr都重定向,
        #  命令的顺序会有些不同.

     关闭文件描述符

    n<&-

    关闭输入文件描述符n.

    0<&-<&-

    关闭stdin.

    n>&-

    关闭输出文件描述符n.

    1>&->&-

    关闭stdout.

    使用exec:

       exec <filename

        命令会将stdin重定向到文件中. 从这句开始, 后边的输入就都来自于这个文件了, 而不是标准输入了(通常都是键盘输入). 这样就提供了一种按行读取文件的方法, 并且可以使用 sed 和 / 或 awk 来对每一行进行分析.

       exec >filename

        命令将会把stdout重定向到一个指定的文件中. 这样所有的命令输出就都会发向那个指定的文件, 而不是stdout.

     示例:exec重定向stdout

    1. #!/bin/bash 
    2. # reassign-stdout.sh 
    3.    
    4.   LOGFILE=logfile.txt 
    5.    
    6.   exec 6>&1           # 将fd 6 与stdout相连接. 
    7.                       # 保存stdout. 
    8.    
    9.  exec > $LOGFILE     # stdout就被文件"logfile.txt"所代替了    
    10.  #---------------------------------------------------------  
    11.  # 在这块中所有命令的输出就都发向文件 $LOGFILE. 
    12.   
    13.  echo -n "Logfile: " 
    14.  date 
    15.  echo "-------------------------------------" 
    16.  echo 
    17.   
    18.  echo "Output of \"ls -al\" command" 
    19.  echo 
    20.  ls -al 
    21.  echo; echo 
    22.  echo "Output of \"df\" command" 
    23.  echo 
    24.  df 
    25.   
    26.  # ----------------------------------------------------------- # 
    27.   
    28.  exec 1>&6 6>&-      # 恢复stdout, 然后关闭文件描述符6. 
    29.   
    30.  echo 
    31.  echo "== stdout now restored to default == " 
    32.  echo 
    33.  ls -al 
    34.  echo 
    35.   
    36.  exit 0 

    示例:exec重定向stdout及stdin

    1. #!/bin/bash 
    2. # upperconv.sh 
    3. # 将一个指定的输入文件转换为大写. 
    4.    
    5.   E_FILE_ACCESS=70 
    6.   E_WRONG_ARGS=71 
    7.    
    8.  if [ ! -r "$1" ]     # 判断指定的输入文件是否可读? 
    9.  then 
    10.    echo "Can't read from input file!" 
    11.    echo "Usage: $0 input-file output-file" 
    12.    exit $E_FILE_ACCESS 
    13.  fi                   #  即使输入文件($1)没被指定 
    14.                       #+ 也还是会以相同的错误退出(为什么?). 
    15.   
    16.  if [ -z "$2" ] 
    17.  then 
    18.    echo "Need to specify output file." 
    19.    echo "Usage: $0 input-file output-file" 
    20.    exit $E_WRONG_ARGS 
    21.  fi 
    22.   
    23.   
    24.  exec 4<&0 
    25.  exec < $1            # 将会从输入文件中读取. 
    26.   
    27.  exec 7>&1 
    28.  exec > $2            # 将写到输出文件中. 
    29.                       # 假设输出文件是可写的(添加检查?). 
    30.   
    31.  # ----------------------------------------------- 
    32.      cat - | tr a-z A-Z   # 转换为大写. 
    33.  #   ^^^^^                # 从stdin中读取.Reads from stdin. 
    34.  #           ^^^^^^^^^^   # 写到stdout上. 
    35.  # 然而, stdin和stdout都被重定向了. 
    36.  # ----------------------------------------------- 
    37.   
    38.  exec 1>&7 7>&-       # 恢复 stout. 
    39.  exec 0<&4 4<&-       # 恢复 stdin. 
    40.   
    41.  # 恢复之后, 下边这行代码将会如期望的一样打印到stdout上. 
    42.  echo "File \"$1\" written to \"$2\" as uppercase conversion." 
    43.   
    44.  exit 0 

    注:使用文件描述符5可能会引起问题. 当Bash使用exec创建一个子进程的时候, 子进程会继承fd5. 最好还是不要用fd5

  • 相关阅读:
    Spring使用Jackson处理json数据
    手工搭建web项目
    购物车模块
    C# ——利用反射动态加载dll
    C# —— 利用Marshal.GetDelegateForFunctionPointer 来转换一个函数指针为一个委托
    C# —— GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。
    c#——IntPtr
    C#-StructLayoutAttribute(结构体布局)
    C#报错——传递数组对象报错“未将对象引用设置到对象的实例”
    C#——保留小数点,强转
  • 原文地址:https://www.cnblogs.com/xlmeng1988/p/2982582.html
Copyright © 2011-2022 走看看