Linux的標準輸入、標準輸出和標準錯誤

韓師學子--胖佳發表於2019-03-02

                  Linux的標準輸入、標準輸出和標準錯誤


什麼是檔案描述符?
檔案描述符是一個簡單的正整數,用以標明每一個被程式所開啟的檔案和socket。
最前面的三個檔案描述符(0,1,2)分別與標準輸入(stdin),標準輸出(stdout)和標準錯誤(stderr)對應。

Unix/Linux/BSD 都有三個特別檔案,分別
1)標準輸入 即 STDIN , 在 /dev/stdin ,
一般指鍵盤輸入, shell裡代號是 0

2) 標準輸出 STDOUT, 在 /dev/stdout,
一般指終端(terminal), 就是顯示器, shell裡代號是 1

3) 標準錯誤 STDERR, 在 /dev/stderr
也是指終端(terminal), 不同的是, 錯誤資訊送到這裡
shell裡代號是

2, 3用些例子再表達一下

User@User-PC ~
$ ls /dev/stdin
/dev/stdin@

User@User-PC ~
$ ls -l /dev/std*
lrwxrwxrwx 1 User Users 15 Mar  1  2008 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 User Users 15 Mar  1  2008 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 User Users 15 Mar  1  2008 /dev/stdout -> /proc/self/fd/1


將標準輸出導向到檔案, ls 1> log1.txt,縮寫就是 ls > log1.txt

User@User-PC ~
$ ls 1> log1.txt

User@User-PC ~
$ cat log1.txt 
Mail/
News/
a.txt
aa*
awkscr
b.txt
bb*
bin/
cc
cgitest.rex*
dd*
irc-sh*
junk
lib/
log1.txt
lynx.cfg
matrix/
perlscr*
pp*
rexx_script/
rrr
testawk
tmp/
trash


標準錯誤的演示

User@User-PC ~
$ ls llll 1> log2.txt
ls: 無法存取 llll: No such file or directory

再次執行,但這次沒有這個檔案llll, 出現錯誤訊息

User@User-PC ~
$ cat log2.txt 

User@User-PC ~
$ file log2.txt
log2.txt: empty

輸出沒有導向到檔案,檔案是空檔案

User@User-PC ~
$ ls llll 2> log2.txt

User@User-PC ~
$ cat log2.txt 
ls: 無法存取 llll: No such file or directory

User@User-PC ~
$ 

再次執行剛才的命令,只是將 1> log2.txt 改為 2> log2.txt
這次就成功把錯誤訊息導向至檔案了

命令 2>&1 > file, 如

User@User-PC ~
$ echo 123 | if grep -E '[0-9]+' 2>&1 > /dev/null ; then echo "This is number."; fi
This is number.


grep 標準輸出和標準錯誤 都導向到系統‘黑洞’,不會再螢幕上顯示什麼

最後再解釋一下:

> 預設為標準輸出重定向,與 1> 相同
2>&1 意思是把 標準錯誤輸出 重定向到 標準輸出.
&>file 意思是把 標準輸出 和 標準錯誤輸出 都重定向到檔案file中

1.&>file或n>&m均是一個獨立的重定向符號,不要分開來理解。
2.明確檔案和檔案描述符的區別。
3.&>file表示重定向標準輸出和錯誤到檔案
例如:
rm -f $(find / -name core) &> /dev/null,/dev/null是一個檔案,這個檔案比較特殊,所有傳給它的東西它都丟棄掉。
4.n>&m表示使檔案描述符n成為輸出檔案描述符m的副本。這樣做的好處是,有的時候你查詢檔案的時候很容易產生無用的資訊,如:2> /dev/null的作用就是不顯示標準錯誤輸出;另外當你執行某些命令的時候,出錯資訊也許很重要,便於你檢查是哪出了毛病,如:2>&1
例如:
注意,為了方便理解,必須設定一個環境使得執行grep da *命令會有正常輸出和錯誤輸出,然後分別使用下面的命令生成三個檔案:

grep da * > greplog1
grep da * > greplog2 1>&2   
grep da * > greplog3 2>&1  //grep da * 2> greplog4 1>&2 結果一樣
#檢視greplog1會發現裡面只有正常輸出內容
#檢視greplog2會發現裡面什麼都沒有
​​​​​​​#檢視greplog3會發現裡面既有正常輸出內容又有錯誤輸出內容

 

相關文章