linux shell I/O重定向小結

      材料總結,大部份內容及示例摘自《Advanced Bash-Scripting Guide》中chapt:An in-depth exploration of the art of shell scripting;須要詳細請自行參看。shell

       對於重定向簡單的解釋就是捕捉一個文件, 命令, 程序, 腳本, 或者甚至是腳本中的代碼塊的輸出, 而後將這些輸出做爲輸入發送到另外一個文件, 命令, 程序, 或腳本中.bash

      默認狀況下始終有3個"文件"處於打開狀態, stdin (鍵盤), stdout (屏幕), and stderr (錯誤消息輸出到屏幕上).ide

      每一個打開的文件都會被分配一個文件描述符.stdin, stdout, 和stderr的文件描述符分別是0, 1, 和 2. 對於正在打開的額外文件, 保留了描述符3到9. 在某些時候將這些格外的文件描述符分配給stdin, stdout, 或者是stderr做爲臨時的副本連接是很是有用。而且在通過複雜的重定向和刷新以後須要把它們恢復成正常的樣子 ui

 

文件描述符:spa

表示範圍:  0-9rest

0-2:是系統定義好的。繼承

         0:表明STDIN,標準輸入進程

         1:表明STDOUT,是標準輸出ip

          2:表明STDERR,是標準錯誤輸出ci

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

相關文章
相關標籤/搜索