IO重定向與文件描述符

1.介紹 linux

IO重定向用於捕捉一個文件,命令,程序,腳本或者代碼塊的輸出,而後把捕捉到的輸出做爲輸入發送給另一個文件,命令,程序或腳本。shell

終端程序通常從單一源以流的形式彙集輸入和顯示輸出,script執行時(進程), 系統會默認開啓3個標準文件,stdin, stdout,stderr . script默認會由stdin讀取數據,默認鍵盤,由stdout輸出執行結果,默認屏幕; 如有錯誤發生,則由stderr顯示信息,默認指向屏幕系統開啓這3個文件時,以文件代碼(分別爲0,1,2)做爲鏈接,這三個文件被稱爲標準I/O.Linux Shell 環境中支持標準輸入輸出重定向,用符號<和>來表示,故能夠用來指定須要重定向的標準輸入或輸出,好比 2>a.txt 表示將錯誤信息輸出到文件a.txt中。bash

同時,還能夠在這三個標準輸入輸出之間實現重定向,好比將錯誤信息重定向到標準輸出,能夠用 2>&1來實現。經常使用的用法之一是將輸出重定向至 /dev/null 來禁止輸出。網絡

 

2. file descriptor FD ide

進程必須先打開一個文件,才能讀取或寫入文件,Linux進程經過給每一個當前被打開的文件賦整數值(從0開始)來追蹤文件,這個整數被稱爲文件描述符,以後對此文件的操做都使用FD來完成。Linux經過/proc 文件系統來檢查當前運行進程打開的文件和文件描述符/proc/pid/fd,pid 即對應進程ID,fd 文件夾下以整數文件描述符命名的符號連接,連接到打開文件自己。函數

每個I/O管道被用一個整數命名,文件描述符能夠與常規文件、設備節點、網絡套接字鏈接(即在虛擬文件系統/proc中,以數字命令的連接文件,連接到指定文件)測試

  其中0,1,2三個特殊的FD,就是STDIN,STDOUT,STDERR,分別指向相應的設備文件this

標準輸入STDIN:程序讀取的源url

標準輸出STDOUT:程序寫入的目的地spa

標準錯誤STDERR:程序將出錯情況報告給一個叫標準錯誤stderr 的目的地

 

FD

默認輸出位置

重定向操做符

STDIN

0

keyboard input

(0)<    (0)<<  

STDOUT

1

mointor

(1)>    (1)>>

STDERR

2

monitor

2>    2>>

 

3. Pipeline and redirection

  Pipe將多個命令鏈接在一塊兒,是Linux的一種基本的進程間通訊技術。它的設計符合Unix哲學:複雜的系統應該由簡單的、專門的、互操做簡單的組件構成,故許多標準Linux程序被設計爲過濾器。

管道:把一個進程的標準輸出流與另外一個進程的標準輸入流鏈接起來,管道符|用於鏈接一個命令的標準輸出與另外一條命令的標準輸入

pipe 命令:pipe 後面接的第一個數據一定是指令,且這個指令必須可以接受stdin 數據並處理, pipe 命令僅處理stdout , 而忽略stderr ,並將處理結果傳遞給標準輸出,如grep , head, tail, cut, sort, expand,sed,awk,fmt,tac,tr,grep,nl,pr , sed ,awk

過濾器(filters):用來接收標準輸入,通過過濾器命令的轉化,再寫到標準輸出。如cat test | grep ade| tac |grep| 即爲過濾器

 

 

4. 重定向

即不使用系統默認的標準輸入輸出,而是從新指定,即輸入重定向,輸出重定向,錯誤輸出重定向,

雙重輸出重定向(一次單獨地送到不一樣的地方)IO重定向其實就是讓已建立的FD指向其它的文件(修改其連接的文件)輸入輸出數據流的位置用FD標識。

IO重定向的原理就是經過exec 來操做FD(修改FD所指向的文件),來實現將輸入和輸出設定爲指定的文件(或設備)。關於重定向須要注意:

  1.  I/O重定向與 FD有關,shellFD一般爲10個,即 09 
  2. IO重定向中,stdout stderr 的管道會先準備好,纔會從 stdin 讀取文檔;
  3. 重定向操做發生的時間是在命令執行開始以前
  4. 對同一個文件描述符屢次進行重定向操做,後發生的會覆蓋先發生的操做,重定向的最終結果是最後一次重定向命令 
  5.   tee 命令是在不影響本來 I/O 的狀況下,將 stdout 複製一份到文檔中去;
  6. bashksh)執行命令的過程:分析命令-變量求值-命令替代(``$( ))-重定向-通配符展開-肯定路徑-執行命令;
  7. ( ) command group 置於子shell 去執行,它會繼承父shellStandard input, output, and error any other open file descriptors, 這就是爲何子shell中執行的命令輸出也同樣會打印到屏幕。

 

 

基本IO重定向

cmd > file stdout 重定向到 file 文件中;

cmd 1> file 同上

cmd >> file stdout 重定向到 file 文件中(追加)

cmd 2> file stderr 重定向到 file 文件中;

cmd 2>> file stderr 重定向到 file 文件中(追加)

 

cmd > file 2>&1 stderr stdout 一塊兒重定向到 file 文件中;

cmd &>file  上一例的簡寫形式

cmd >> file 2>&1 stderr stderr 一塊兒重定向到 file 文件中(追加)

cmd >/dev/null 2>/dev/null 不記錄標準輸出或標準錯誤輸出

cmd &>/dev/null 同上

 

cmd < file cmd 命令以 file 文件做爲 stdin

cmd < file >file2 cmd 命令以 file 文件做爲 stdin,以 file2 文件做爲 stdout

cmd << delimiter Here document,從 stdin 中讀入,直至遇到 delimiter 分界符。

 

示例說明

find / -name 2>/dev/null

date>file1  標準輸出無內容,file1中有內容。(先執行重定向)

(date)>file1  標準輸出無內容,file1中有內容。(先將子shell 標準輸出重定向至file1)

(date >file1) >file2 file1中有內容,file2中無內容。(將子shell 標準輸出重定向至file2;shell,date標準輸出重定向至file1,shell標準輸出沒有內容,file1中有內容)

date >file1 >file2  file1中無內容,file2中有內容。(date 標準輸出重定向至file1,而後再將date標準輸出重定向至file2,都是針對同一個文件描述符,會覆蓋.

 

> test.txt 新建空白文件,或者清空文件(危險命令), 多用於清空日誌

> /dev/sda 會致使整個塊設備的數據丟失

 

 

5. IO重定向符號彙總

 

cmd n>file

FDn的輸出寫入file

cmd >file

標準輸出寫入file FD1即將標準輸出重定向到file

>  1>的簡寫形式

cmd n<file

file讀入到FD n

cmd <file

file 讀入標準輸入中 FD0, 即將標準輸入重定向到file

< 0<的簡寫形式

cmd n>>file

FDn的輸入追加寫入到file

cmd >>file

追加輸出至file,FD1

cmd >|file

忽略shellnoclobber選項,強制覆蓋file

cmd  n>|file

忽略noclobber選項(shell選項),強制將FDn的輸出寫入file

cmd n>>|file

忽略noclobber選項

<<delimiter

here-document

cmd1 | cmd2

管道符|(特殊IO重定向), cmd1的標準輸出做爲cmd2的標準輸入

 

5.腳本中臨時重定向每一行

此方法能夠爲生成錯誤消息提供方便

cat retest.sh

#!/bin/bash

echo "this is an error" >&2                 #重定向至指定FD,此處重定向至標準錯誤輸出

echo "this is normal output"

echo "redirect this line to standard output" >&1

 

[ade@h test]$ ./test.sh >test1 2>test2

[ade@h test]$ cat test1

this is normal output

redirect this line to standard output

[ade@h test]$ cat test2

this is an error

 

7. 腳本中代碼塊重定向

代碼重定向是指在代碼塊內將標準輸入或標準輸出重定向到文件,而代碼塊以外而保持默認狀態(即重定向只對代碼塊有效,而不是整個腳本),它可讓代碼塊方便的處理一個文件,它也是腳本中的臨時重定向,特別之處是它針對的是shell腳本中相應的結構代碼。

while,until,for,if/then, 函數等代碼塊均可以使用重定向,<輸入重定向,>輸出重定向。

 

cat rewhile.sh

#!/bin/bash

 

ls /etc > loggg

while [ "$filename" != "rc.d" ]

do

read filename

let "count +=1"

done < loggg

 

echo "$count times read"

 

#測試循環體外的標準輸入是否被重定向

echo -n " ------pls input data:---------"

read test

echo $test

 

 

cat reif.sh

if [ -z "$1" ]

then

echo "positional parameter is null"

fi > loggg

echo "-----------Normal stdout--------"

 

 

其它結構的重定向

for

do

......

done < loggg

 

if [condition]

then

...

else

...

fi < loggg

 

until [condition]

do

    ...

done < loggg

 

 

8. 腳本中永久重定向全部命令

當但願將腳本中的不少輸出都重定向時,可使用exec 通知shell在腳本執行時重定向特定的文件描述符。實例上是使用exec 來完成FD的相關操做。

 cat test1.sh

#!/bin/bash

 

exec 1>testout

echo "line one"

echo "line two"

echo "line three"

 

 

 cat test.sh

#!/bin/bash

 

exec 2>testerr

echo "this is the start of the script"

 

echo "the following command will redirect all ouptput to testout"

exec 1> testout    #or exec > testout

 

echo " put this line into testout"

echo "put this line into testerr" >&2

 

[ade@h test]$ ./test.sh

this is the start of the script

the following command will redirect all ouptput to testout

[ade@h test]$ cat testout

 put this line into testout

[ade@h test]$ cat testerr

put this line into tester

 

 

refer

Linux下輸入輸出重定向

Linux重定向(百度百科)

man bash   here documents 部分

awk, fold, grep, head, nnkf, pr, sed, sort, tail, tee, tr, uniq, wc

exec

lsof  : 列出全部開放的文件描述符

here-document

Linux輸入輸出錯誤重定向

相關文章
相關標籤/搜索