0.引言
在Linux系統中,我們在Terminal中能夠第一時間看到某條命令的即時反饋,
$ ls -Ss /
total 152
80 tmp 0 dev 4 home 4 opt 4 srv 0 run 0 lib64 0 lib
16 lost+found 4 boot 4 media 4 root 4 usr 0 libx32 0 sbin 0 proc
12 etc 4 cdrom 4 mnt 4 snap 4 var 0 lib32 0 bin 0 sys
這是系統默認將執行結果輸出到屏幕上。Linux萬物皆為文件,屏幕也不例外,系統將其定義為stdout。與之對應,定義鍵盤為stdin,同時捕捉到的錯誤接入stderr文件。當然,這三個文件絕非虛無縹緲的抽象概念,而是可觸可摸的具象存在。
$ ls -l /dev/std*
lrwxrwxrwx 1 root root 15 Jul 2 15:02 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jul 2 15:02 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jul 2 15:02 /dev/stdout -> /proc/self/fd/1
讀到上面的輸出結果,真忍不住要為Linux歡呼,一切皆為文件!
我們同時也能看到 stdin,stdout,stderr 分別分配到了三個 fd(file-descriptor)。
$ ls -l /dev/std*
/dev/stdin -> /proc/self/fd/0
/dev/stdout -> /proc/self/fd/1
/dev/stderr -> /proc/self/fd/2
正是如此精妙的設計,我們得以直接使用fd所指示的數字索引具體的文件。
1.最高頻的用法
每天必用的操作是
mpv 乘風破浪的姐姐.mkv &> /dev/null &
這段命令指示mpv播放器播放#乘風破浪的姐姐#并將結果和錯誤報告導入進/dev/null文件。遺憾的是,雖然很便捷,但我們從中看不到任何 file-descriptior。我們將其完整性寫下來:
mpv 乘風破浪的姐姐.mkv 2>&1 > /dev/null &
此時便一目了然,stderr(2)先合并進stdout(1),之后共同輸入到 /dev/null 文件中, 最后面的 & 指示程序并列運行。
2.基礎用法
Redirection的基礎用法總結如下:
ps -ef > ps.txt # 重定向輸出到 ps.txt文件,同時完全覆蓋原內容
ps -ef >> ps.txt # 雙>表示Append(追加),不覆蓋原先的內容
ps ef 2> ps-err.txt # 重新定向錯誤報告到指定文件
ps -ef 2>&1 > ps.txt # 合并stdout stderr到指定文件
以上四項為redirection的地基。
3.高階用法
前面兩節,Redirection處理的只有stdin(鍵盤)和stdout(屏幕)。使我們錯覺,重定向的功能僅限于刻板的鍵盤和屏幕。linux中,萬物皆為文件,因此只要Redirection能處理文件,它就能處理萬物。真相也正是如此,如我們在引言中所探討,鍵盤與屏幕只是文件的一種。
下面我們探討完全以文件作為輸入和輸出,先查看province.txt文件:
$ cat provinces.txt
beijing shangdong shanghai guangzhou jiangsu
將文件內的‘空格’分割符替換為‘逗號’分隔符
$ tr " " "," < provinces.txt
beijing,shangdong,shanghai,guangzhou,jiangsu
還可以更進一步,將修改的結果寫進新的文件:
$ tr " " "," < provinces.txt > provinces-new.txt
$ cat provinces-new.txt
beijing,shangdong,shanghai,guangzhou,jiangsu
4.拍案叫絕的 Here Documents
Redirection最教人拍案叫絕的是應用于 Here Documents
$ cat <<EOF | grep 'b' | tee b.txt
> foo
> bar
> baz
> EOF
bar
baz
$ cat b.txt
bar
baz
內嵌入代碼中要加hypen(-)鏈接符號
if true; then
cat <<-HERE
a
HERE
fi
5.收尾總結
Linux系統指定stdin,stdout, stderr 為從0到2的3個file descriptor。
最高頻的應用是:
mpv 乘風破浪的姐姐.mkv &> /dev/null &
作為基礎的四個方法:
ps -ef > ps.txt # 重定向輸出到 ps.txt文件,同時完全覆蓋原內容
ps -ef >> ps.txt # 雙>表示append(追加),不覆蓋原先的內容
ps ef 2> ps-err.txt # 重新定向錯誤報告到指定文件
ps -ef 2>&1 > ps.txt # 合并stdout stderr到指定文件
高階用法:
$ tr " " "," < provinces.txt > provinces-new.txt
Here Documents
$ cat <<EOF | grep 'b' | tee b.txt
> foo
> bar
> baz
> EOF