Linux Basics-重定向與管道:第一部分

Linux Basics-重定向與管道:第一部分

概述

本教程將介紹 Linux 中重定向標準 IO 流的基本技術。學習:

  • 什么是重定向與標準 IO 流:標準輸入、標準輸出和標準錯誤

  • 各種流和管道的實際應用

 


前提條件

你應該了解 Linux 基本知識以及擁有一個正常工作的 Linux 系統,在本文說明的實例中,我采用是CentOS 7 內核版本是3.10,它適用于大多數linux(如果不知道自己的內核版本,可以通過在命令行中輸入命令uname -a來查詢 )

 

重定向和流

在linux發展到今天,許多工作是通過腳本來完成,這樣做的好處就是可以提高效率,而且運維人員可以做到自動化的運維,省去了每天重復一樣的操作,而且也避免了因為個人失誤而帶來的許多問題,想要做到自動化運維就少不了要編寫bash腳本,linux中重要的哲學就是避免要和用戶交互,而且重定向和流的使用就是完全符合了這樣的要求。


概念介紹

 文件描述符(File descriptor)

在操作系統中每個程序的打開都要經過系統管理,而系統管理進程或者程序的運行就是通過文件描述符來管理,文件描述符在形式上是一個非負整數。實際上,它是一個索引值,指向內核為每一個進程所維護的該進程打開文件的記錄表。當程序打開一個現有文件或者創建一個新文件時,內核向進程返回一個文件描述符。在程序設計中,一些涉及底層的程序編寫往往會圍繞著文件描述符展開。每個Unix進程(除了可能的守護進程)應均有三個標準的POSIX文件描述符,對應于三個標準流:

整數值

名稱

<stdio.h>文件流

0

Standard input

stdin

1

Standard output

stdout

2

Standard error

stderr

 

stdout是 標準輸出流,它顯示來自命令的輸出。它擁有文件描述符 1。

stderr是 標準錯誤流,它顯示來自命令的錯誤輸出。它擁有文件描述符 2。

stdin是 標準輸入流,它向命令提供輸入。它擁有文件描述符 0。

 

重定向標準 IO

盡管標準輸入和輸出模型是發往和來自 ASCII 終端的順序字符流,但是我們想要把文本文件中的字符發給終端,或者是想要上一條命令的結果發給某個文件或者程序,總之需求多多,這個時候就要用到重定向

重定向是以出現的順序進行處理的,從左到右。

注意重定向的順序非常重要。例如,命令

ls > dirlist 2>&1

將標準輸出和標準錯誤重定向到文件 dirlist, 而命令

ls 2>&1 > dirlist

只會將標準輸出重定向到文件 dirlist, 因為在標準輸出被重定向到文件 dirlist 中之前,標 準錯誤被復制為標準輸出。

一些文件名在重定向中被 bash 特殊處理,如下表所示:

/dev/fd/fd

如果 fd 是一個合法的整數,文件描述符 fd 將被復制 。

/dev/stdin

文件描述符 0 被復制。

/dev/stdout

文件描述符1 被復制 。

/dev/stderr

文件描述符2 被復制 。

/dev/tcp/host/port

如果host 是一個合法的主機名或internet地址 ,并且 port 是一個整數端口號或服務名,bash 試圖建立與相應的socket (套 接 字 )的TCP連接。

/dev/udp/host/port

如果 host 是一個合法的主機名或Internet地址,并且 port 是一個整數端口號或服務名,bash試圖建立與相應的socket (套 接 字 )的UDP連接。

打開或創建文件錯誤將導致重定向出錯 


 1.重定向輸出Redirecting Output

它的格式是


[n]>word

 

可通過兩種方式將輸出重定向到文件:

<1>Redirecting Output 重定向輸出

格式:

n>word

將來自文件描述符 n的輸出重定向到某個文件。您必須擁有該文件的寫權限。如果該文件不存在,則需要創建它。如果它已經存在,通常會毫無預兆地丟失現有內容。

 

<2>Appending Redirected Output (添加到重定向后的輸出尾部)

格式:

n>> word

這種方式的輸出重定向使得以 word 擴展結名的文件被打開并通過文件描述符 n 從尾部添加。如果文件不存在,它將被創建。如果它已經存在,輸出會被附加到現有文件。n> 或 n>> 中的 n指的是 文件描述符。如果省略它,則會假設使用的是標準輸出(文件描述符 1)

 

可以使用內建命令 set的 noclobber選項來控制此行為。如果已設置它,可以使用 n>| 覆蓋它。如果啟用了內建命令 set 的 noclobber 選 項 , 那么如果 word 擴展后得到的文件名 存在并且是一個普通的文件,重定向將失敗。 如果重定向操作符是 >|, 或者重定向操作符 是 > 并且沒有啟用內建命令 set 的 noclobber 選 項 , 那么即使 word 得出的文件名存 在 也會嘗試進行重定向。

set -o noclobber命令或者set +C 來控制,set -C來取消,具體操作可以查看man幫助

 

下面是說明的演示:

LIST 1 . 創建準備文件

 

  mkdir -p cdx1&& cd cdx1 && { 
  echo -e "1 magedu\n2 linux\n3 M21" > text1 
  echo -e "4\tlear\n3\tkernel\n10\knowledge" > text2 
  echo "www.magedu.com. " >text3 
  ls; }

 

LIST 2 . 輸出重定向

 blob.png

從上述例子可以看出 文件描述符不同n>或者n>>重定向的內容也是不同的,而且n>和n>>作用也是不同,n>>可以重定向到尾部。


拓展知識(自行探索)

有時,您可能希望將標準輸出和標準錯誤都重定向到一個文件中。通常,會對自動化流程或后臺作業這么做,以便可以在以后檢查輸出。使用 &> 或 &>> 將標準輸出和標準錯誤都重定向到同一個位置。另一種方法是重定向文件描述符 n,然后使用結構 m>&n 或 m>>&n 將文件描述符 m重定向到相同位置。重定向輸出的順序很重要。例如,

command 2>&1 >output.txt
不同于 
command >output.txt 2>&1
在第一種情況下,stderr 被重定向到當前的 stdout 位置,然后將 stdout 重定向到 output.txt,但第二次重定向僅會影響 stdout,而不會影響 stderr。在第二種情況下,stderr 被重定向到當前的 stdout 位置,也就是 output.txt

 

Redirecting Standard Output and Standard Error 

Bash 允許使用這種結構將標準輸出和標準錯誤 (文件描述符 1 和 2) 重定向到以 word 擴 展結果為名的文件中。

有兩種重定向標準輸出/標準錯誤的形式:

&>word

還 有

>&word

兩種形式中 ,推薦使用第一種。它與

>word 2>&1

在語義上等價 。

 

Opening File Descriptors for Reading and Writing 

重定向操作符

[n]<>word

使得以 word 擴展結果為名的文件被打開 ,通過文件描述符n 進行讀寫。如果沒有指定 n 那么就使用文件描述符0。如果文件不存在,它將被創建。

如下所示

 blob.png

blob.png

blob.png

Moving File Descriptors 
重 定 向 操 作 符

[n]<&digit?

將文件描述符 digit 移動為文件描述符 n, 或標準輸入 (文件描述符 0),如果沒有指定 n 的 話 。 digit 復制為 n 之后就被關閉了。

類似的 重定向操作符

[n]>&digit?

將文件描述符 digit 移動為文件描述符 n, 或標準輸出(文件描述符1),如果沒有指定 n 的 話 。

 


<3>Here Documents 
它將 << 和一個單詞結合構成一個標記,比如與 END 結合來表示輸入結束。LIST 3和4演示了此概念,LIST 3和4使用命令替換創建了一個強制制表符,然后創建了一段僅包含兩個 cat命令的很短的 shell 腳本,每個命令從一個 here-document 讀取信息。使用 END 作為從終端讀取的 here-document 的標記。如果在腳本中使用同一個單詞作為標記,則會導致過早結束輸入。所以,可使用 EOF 代替。創建腳本后,使用 .(點號)命令 導入它(.(點號)和source命令一樣,用于不重啟shell來讀取腳本或者配置文件生效)。

這種重定向使得shell從當前源文件讀取輸入 ,直到遇到僅包含 word 的一行(并且沒有尾部空白,trailing blanks)為止。直到這一點的所有行被用作命令的標準輸入 。

here-document 的格式是:

<<[?]word 
here-document 
delimiter

如果重定向操作符是 <<?, 那么所有前導的tab 字符都被從輸入行和包含 delimiter 的行 中刪除。這樣使得 shell 腳本中的here-document 可以被更好地縮進。

注意:

  • 結尾的delimiter 一定要頂格寫,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 縮進。

  • 開始的delimiter前后的空格會被忽略掉。

  • 格式中word就是delimiter的意思

 


<4>Here Strings 
here-document 的變種 ,形式是

<<<word

word 被擴展 ,提供給命令作為標準輸入。

 

LIST 3 . 使用 here-document 的輸入重定向

blob.png

 

LIST 4 . 使用 here-document 的輸入重定向

 

blob.png

blob.png

 


<5>/dev/null 文件

如果希望執行某個命令,但又不希望在屏幕上顯示輸出結果,那么可以將輸出重定向到 /dev/null:

$ command > /dev/null

/dev/null 是一個特殊的文件,寫入到它的內容都會被丟棄;如果嘗試從該文件讀取內容,那么什么也讀不到。但是 /dev/null 文件非常有用,將命令的輸出重定向到它,會起到”禁止輸出“的效果。

如果希望屏蔽 stdout 和 stderr,可以這樣寫:

 

$ command > /dev/null 2>&1

 


2. 重定向輸入(Redirecting Input )

重定向輸入使得以 word 擴展結果為名的文件被打開并通過文件描述符 n 讀取 ,如果沒有指定 n 那么就作為標準輸入(文件描述符為0)讀取 。

重定向輸入的一般形式是:

[n]<word

 

具體用法參見重定向輸出

命令

說明

command > file

將輸出重定向到 file。

command < file

將輸入重定向到 file。

command >> file

將輸出以追加的方式重定向到 file。

n > file

將文件描述符為 n 的文件重定向到   file。

n >> file

將文件描述符為 n 的文件以追加的方式重定向到 file。

n >& m

將輸出文件 m 和 n 合并。

n <& m

將輸入文件 m 和 n 合并。

<< tag

將開始標記 tag 和結束標記   tag 之間的內容作為輸入。


重定向用法整理(來自網絡)

簡單重定向

  • cmd > file

把cmd命令的輸出重定向到文件file中。如果file已經存在,則清空原有文件,使用bash的noclobber選項可以防止覆蓋原有文件。

  • cmd >> file

把cmd命令的輸出重定向到文件file中,如果file已經存在,則把信息加在原有文件后面。

  • cmd < file

使cmd命令從file讀入

  • cmd << text

從命令行讀取輸入,直到一個與text相同的行結束。除非使用引號把輸入括起來,此模式將對輸入內容進行shell變量替換。如果使用 <<- ,則會忽略接下來輸入行首的tab,結束行也可以是一堆tab再加上一個與text相同的內容,可以參考后面的例子。

  • cmd <<< word

把word(而不是文件word)和后面的換行作為輸入提供給cmd。

  • cmd <> file

以讀寫模式把文件file重定向到輸入,文件file不會被破壞。僅當應用程序利用了這一特性時,它才是有意義的。

  • cmd >| file

功能同>,但即便在設置了noclobber時也會覆蓋file文件,注意用的是|而非一些書中說的!,目前僅在csh中仍沿用>!實現這一功能。

使用文件描述符的重定向

使用文件描述符的重定向都使用了&符號。

cmd >&n

把輸出送到文件描述符n

cmd m>&n

把輸出 到文件符m的信息重定向到文件描述符n

cmd >&-

關閉標準輸出

cmd <&n

輸入來自文件描述符n

cmd m<&n

m來自文件描述符n

cmd <&-

關閉標準輸入

cmd <&n-

移動輸入文件描述符n而非復制它。(需要解釋)

cmd >&n-

移動輸出文件描述符 n而非復制它。(需要解釋)

注意: 
>&實際上復制了文件描述符,這使得ls > dirlist 2>&1ls 2>&1 > dirlist的效果不一樣。man bash的Redirection節中提及了這段內容。

重定向的組合應用

cmd 2>file

把文件描述符2重定向到file,即把錯誤輸出存到file中。

cmd > file 2>&1

把標準錯誤重定向到標準輸出,再重定向到file,即stderr和stdout都被輸出到file中

cmd &> file

功能與上一個相同,更為簡便的寫法。

cmd >& file

功能仍與上一個相同。

cmd > f1 2>f2

把stdout重定向到f1,而把stderr重定向到f2

 


參考資料

IBM中國linux專區

Wiki

Redirection Definition  http://www.linfo.org/redirection.html

網絡博客

原創文章,作者:M21-郝建勛,如若轉載,請注明出處:http://www.www58058.com/54471

(0)
M21-郝建勛M21-郝建勛
上一篇 2016-10-29
下一篇 2016-10-29

相關推薦

  • 沉舟側畔千帆進,枯木頭前萬樹春

    N21第五周博客作業 1、  顯示/boot/grub/grub.conf中以至少一個空白字符開頭的行; ~]#  grep -E "^[[:space:]]+" //boot/grub/grub.conf root (hd0,0) kernel /vmlin…

    Linux干貨 2016-07-29
  • bash腳本編程實例

    bash腳本編程實例 1.寫一個腳本,判斷當前系統上所有用戶的shell是否為可登錄的shell(即用戶的shell不是/sbin/nologin),分別統計這兩類用戶的個數(通過字符串比較來實現) #!/bin/bash cat /etc/passwd|awk -F: ‘BEGIN{nologin=0;login=0}{if($NF==”/sbin/nol…

    Linux干貨 2017-08-28
  • 文本處理工具sed

    處理文本的工具sed     stream EDitor,行編輯器     sed是一種流編輯器,他一次處理一行內容。處理時,把當前處理的行存儲在臨時緩沖區中,成為“模式空間”(pattern space),接著用sed命令處理緩存區中的內容,處理完成后,把緩沖區的內容送往屏幕?!?/p>

    Linux干貨 2016-08-10
  • 計算機與操作系統

    計算機系統=Hardware+Software Linux操作系統=GNU/kernel+程序 (user space) ————– apps   shell    (人機交互接口) lib call(半層)  (kernel space) —&#…

    Linux干貨 2017-02-14
  • find 和 壓縮工具

    find命令 一、find命令基本介紹 1、find作用 通過遍歷指定路徑實時查找符合條件的文件。 find工作特點 2、find工作特點 ?查找速度較慢 ?精確查找 ?實時查找 ?用戶只能搜索有讀取和執行權限的目錄 3、語法 find [OPTIONS]… [查找路徑] [查找條件] [處理方式] 查找路徑:指定…

    Linux干貨 2016-08-16
  • Nginx反向代理原理、壓測及模塊功能的實現

    基本架設 反向代理模塊 緩存功能的實現 修改報文首部IP 向后端轉發時是否讓客戶端知道 在http中定義緩存基本屬性 定義當后端服務宕機時過期緩存生效條件 報文首部模塊,自定義報文首部 負載均衡模塊1 負載均衡模塊2 負載均衡模塊的常用調度方法1 負載均衡常用調度方法2 與http想等的動態負載均衡模塊1 與http想等的動態負載均衡模塊2 這里讓我們對之前…

    2016-10-30
欧美性久久久久