I/O重定向,即輸入/輸出重定向,是指把命令行的輸入重定向爲從文件中獲取內容,也可以把命令行的輸出結果重定向到文件中。
1.標準輸入、標準輸出和標註錯誤
輸出主要有兩種:一種是程序運行的結果,即該程序生成的數據;一種是狀態和錯誤信息。
我們知道,UNIX的思想是“一切都是文件”,類似ls
的程序實際上也是把運行結果發送到了一個成爲標準輸出(standard output, stdout)的特殊文件中,狀態信息則發送到一個稱爲標準錯誤(standard error, stderr)的文件中。默認情況,這兩個文件都被鏈接到屏幕上,並且不會保存在磁盤文件中。
另外,許多程序從一個稱爲標準輸入(standard input, stdin)的設備來得到輸入,標準輸入默認鏈接到鍵盤。
1.1 標準輸出重定向
使用重定向操作符">"
,後面接文件名,就可以把標準輸出重定向到另一個文件中,若文件不存在,則創建文件;若文件存在,則從文件的首位置開始覆蓋文件。
例如
$ ls -l ./ > ls-output.txt
$ less ls-output.txt
輸出
total 8
-rw-rw-r-- 1 lixj lixj 0 Jun 3 18:18 ls-output.txt
-rw-rw-r-- 1 lixj lixj 100 Jun 3 17:59 ls.txt
-rw-rw-r-- 1 lixj lixj 210 Jun 3 18:02 test1.txt
ls-output.txt (END)
如果不希望覆蓋之前的文件,可以使用重定向操作符">>"
來實現,例如
$ ls -l ./ >> ls-output.txt
$ less ls-output.txt
輸出爲
total 8
-rw-rw-r-- 1 lixj lixj 0 Jun 3 18:20 ls-output.txt
-rw-rw-r-- 1 lixj lixj 100 Jun 3 17:59 ls.txt
-rw-rw-r-- 1 lixj lixj 210 Jun 3 18:02 test1.txt
total 12
-rw-rw-r-- 1 lixj lixj 159 Jun 3 18:20 ls-output.txt
-rw-rw-r-- 1 lixj lixj 100 Jun 3 17:59 ls.txt
-rw-rw-r-- 1 lixj lixj 210 Jun 3 18:02 test1.txt
ls-output.txt (END)
1.2 標準錯誤重定向
一個程序可以把生成的輸出內容發送到任意文件流中,如果把這些文件流中的前三個分別對應標準輸入文件、標準輸出文件和標準錯誤文件,那麼shell將在內部用文件描述符分別索引它們爲0、1和2。即標準錯誤等同於文件描述符2。
所以可以使用如下表示方法來重定向標準錯誤
$ ls -l ./nothing/ 2> ls-error.txt
1.3 將標準輸出和標準錯誤重定向到同一文件
$ ls -l ./nothing &> ls-output.txt
1.4 處理不想要的輸出
命令執行後,如果我們不希望得到輸出,系統提供了一種方法,即通過把輸出重定向到一個稱爲/dev/null的特殊文件中來實現它。
$ ls -l ./nothing 2> /dev/null
1.5 標準輸入重定向
cat
:合併文件
cat命令讀取一個或多個文件,並將它們複製到標準輸出文件中,格式爲:
cat [file...]
例如:
$ cat ls-output.txt
顯示ls-output.txt文件中的內容.cat
用來顯示比較短的文件。其優點是把文件連接在一起顯示。例如
$ cat *.txt
也可以將其合併在一起
$ cat *.txt > all.txt
如果只使用cat
而不帶任何參數,那麼將等待標準輸入(默認鍵盤)讀取內容,直到Ctrl+D結束,並在標準輸出文件,即屏幕中輸出。
$ cat
12345
也可以將其重定向到文件中
$ cat > cat_test.txt
12345
cat也可以從標準輸入重定向中獲取輸入,使用"<"
.
$ cat < cat_test.txt
2. 管道
命令從標準輸入到讀取數據,並將數據發送到標準輸出的能力,是使用了名爲管道的shell特性。使用管道操作符“|”
可以把一個命令的標準輸出傳送到另一個命令的標準輸入中。
commend1 | commend2
例如
$ ls -l ./ | less
以上代碼即使用less分頁顯示任意命令的輸出,並將其結果發送到標準輸出
2.1 過濾器
管道經常用來對數據執行復雜的操作。也可以把多條命令合在一起構成一個管道。這種方式中用到的命令通常被稱爲過濾器(filter)。
sort
: 排序,將輸入排序
$ ls /bin /usr/bin | sort | less
以上代碼將/bin和/usr/bin目錄下所有可執行程序合併成一個列表,並且按照順序排列,最後再查看這個列表。
uniq
:報錯或忽略文件中重複的行
uniq
可以接受來自於標準輸入或者一個單一文件名參數對應的已排好序的數據列表。默認情況下,該命令刪除列表中所有重複行。因此,在管道中添加uniq
命令,可以確保所有的列表都沒有重複行。
例如
$ ls /bin/ /usr/bin/ | sort | uniq | less
如果反過來想查看重複的列表,可以增加參數-d
$ ls /bin/ /usr/bin/ | sort | uniq -d | less
wc
:打印行數、字數和字節數
wc
(字數統計,word count)命令用來顯示文件中包含的行數、字數和字節數。
$ wc ls-output.txt
輸出
1 9 57 ls-output.txt
可以使用-l
參數限制只顯示行數,我們查看已經排好序的列表中的條目數,可以
$ ls /bin/ /usr/bin/ | sort | uniq | wc -l
輸出
1376
grep
:打印匹配行
它用來在文件中查找匹配文本, 使用方法爲
grep pattern [file...]
如果想讓我們從列出的程序中搜索出文件名包含zip的所有文件,
$ ls /bin /usr/bin | sort | uniq | grep zip
輸出
bunzip2
bzip2
bzip2recover
funzip
gpg-zip
gunzip
gzip
unzip
unzipsfx
zipdetails
zipgrep
zipinfo
grep有用的兩個選項爲:-i,該選項使得grep在搜索時忽略大小寫;-v,該選項使得grep只輸出和模式不匹配的行.
head/tail
:打印文件的開頭部分/結尾部分
head命令將輸出文件的前10行,tail命令則輸出文件名的最後10行。也可以通過-n
參數來修改輸出的行數
$ head -n 5 ls-output.txt
$ tail -n 5 ls-output.txt
也可用於管道中
$ ls /usr/bin | tail -n 5
以上代碼輸出最後5個程序(往往是z開頭的)
tail可以使用-f
參數來實時查看文件.
tee
: 從stdin讀取數據,並同時輸出到stdout和文件
tee程序讀取標準輸入,再把讀取到的內容複製到標準輸出,和一個或更多的文件中去。
例如
$ ls /usr/bin/ | tee ls.txt | grep zip
在查找zip的同時,還將所有/usr/bin內的程序名保存到了ls.txt中