shell中的輸入輸出重定向——shell程式設計學習_四
輸入輸出重定向
一般情況,我們的標準輸入是鍵盤,標準輸出是終端顯示器;但是在很多情況,我們需要從檔案中讀取資料作為輸入,然後將輸出資料儲存在檔案中。這是我們就需要將標準輸入從鍵盤重定向到檔案,將標準輸出重定向到檔案,這個過程就是輸入輸出重定向。
輸出重定向
輸出重定向有兩種方式
COMMAND > outputfile
COMMAND >> outputfile
其中>
和>>
是輸出重定向的符號,前後必須有空格(這也是為什麼要將大於號轉義)。
>
和>>
的區別
>
示例:
[root@shell io_redirection]# pwd/mnt/io_redirection [root@shell io_redirection]# echo fsx.com fsx.com [root@shell io_redirection]# echo fsx.com > test.txt [root@shell io_redirection]# cat test.txt fsx.com
如果使用>
重定向資料到一個已經有內容的檔案,會完全覆蓋原來的內容
[root@shell io_redirection]# ls test.txt [root@shell io_redirection]# cat test.txt fsx.com[root@shell io_redirection]# echo qq > test.txt [root@shell io_redirection]# cat test.txt qq
有時候我們不希望覆蓋源有資料,這時候就需要使用>>
來完成操作,我們稱之為追加操作
[root@shell io_redirection]# ls test.txt [root@shell io_redirection]# cat test.txt qq [root@shell io_redirection]# echo fsx.com >> test.txt [root@shell io_redirection]# cat test.txtqq fsx.com //注意,不是緊跟追加,而是另起一行
輸入重定向
輸入重定向使用COMMAND < outputfile
來完成操作,將檔案內容輸出給命令。
[root@shell io_redirection]# cat < test.txt qq fsx.com [root@shell io_redirection]# cat < test.txt > test2.txt//同時輸入重定向,輸出重定向,將test.txt輸入重定向到cat,再輸出重定向到test2.txt中 [root@shell io_redirection]# ls test2.txt test.txt [root@shell io_redirection]# cat test2.txt qq fsx.com
內聯輸入重定向
使用格式:
COMMAND << marker //命令 << 標示符
data input //資料的輸入
marker //提示符,成對出現
具體示例:
[root@shell io_redirection]# result=`bc << eof scale=3 var1=3.14 var2=2 var3=var1*var2 print var3 > eof` [root@shell io_redirection]# echo $result 6.28
檔案描述符與錯誤重定向
檔案描述符
在Linux系統中,將每個物件當作檔案處理(Linux的核心思想,一切皆檔案),包括輸入輸出的過程。
Linux用檔案描述符來表識每一個檔案物件。
檔案描述符是一個非負整數,用來唯一標識會話中開啟的檔案。
每一個過程一次最多可以有 9 個檔案描述符
LInux中shell提供三個檔案描述符:
檔案描述符 | 縮寫 | 描述 |
---|---|---|
0 | STDIN | 標準輸入 |
1 | STDOUT | 標準輸出 |
2 | STDERR | 標準錯誤 |
錯誤重定向
標準輸入輸出重定向:COMMAND 1> outputfile
,COMMAND 0< outputfile
預設情況下,標準輸入輸出不需要指定檔案描述符。但是如果對錯誤資訊進行重定向是,就必須使用 2 來進行描述:COMMAND 2> outputfile
[root@shell io_redirection]# cat fsx//當我們試圖訪問一個不存在的檔案,系統會輸出標準錯誤到終端 cat: fsx: No such file or directory [root@shell io_redirection]# cat fsx 2> test4.txt//我們使用標準錯誤描述符,將錯誤資訊重定向到一個檔案中,則錯誤資訊就被輸出到該檔案中 [root@shell io_redirection]# cat test4.txt cat: fsx: No such file or directory
這是我們進行錯誤捕獲和錯誤處理的重要方式。
特別是,當我們的輸出有正確輸出,也有錯誤輸出的時候,就可以使用檔案描述符,將其分看,方便進一步處理
[fsx@shell ~]$ find /etc/ -name passwd* 1>find_out.txt 2>find_err.txt //將標準輸出寫入find_out.txt檔案,將標準錯誤寫入find_err.txt檔案 [fsx@shell ~]$ cat find_out.txt /etc/pam.d/passwd /etc/passwd- /etc/passwd [fsx@shell ~]$ cat find_err.txt find: `/etc/lvm/cache': Permission denied find: `/etc/lvm/backup': Permission denied find: `/etc/lvm/archive': Permission denied find: `/etc/dhcp': Permission denied find: `/etc/audisp': Permission denied find: `/etc/selinux/targeted/modules/active': Permission denied find: `/etc/audit': Permission denied find: `/etc/pki/rsyslog': Permission denied find: `/etc/pki/CA/private': Permission denied find: `/etc/sudoers.d': Permission denied
在指令碼中重定向輸入輸出
輸出重定向
shell指令碼中輸出重定向分為兩種,一種是臨時重定向,一種是永久重定向。
臨時重定向:
COMMAND >&檔案描述符
[root@shell io_redirection]# cat test.sh #!/bin/bash echo "test error" >&2//定義了一個錯誤資訊,提供了我們自定義錯誤資訊的能力 echo "normal output" //編寫一個指令碼檔案test.sh,具體內容如上 [root@shell io_redirection]# bash test.sh //如果執行bash,都會顯示,看起來沒什麼差別,這是因為標準錯誤也是通過標準輸出的形式體現。 test error normal output [root@shell io_redirection]# bash test.sh 2>>errlog//如果我們將標準錯誤重定向到errlog檔案中,則只顯示標準輸出 normal output [root@shell io_redirection]# cat errlog //檢視檔案中重定向的標準錯誤 test error
永久重定向:
exec 檔案描述符>檔名
將一個檔案描述符值(1/2)定給一個檔案。
[root@shell io_redirection]# cat test2.sh #!/bin/bash exec 1>testout.txt echo "normal output 1" echo "normal output 2" [root@shell io_redirection]# bash test2.sh [root@shell io_redirection]# cat testout.txt normal output 1 normal output 2 //這就將輸出全部重定向到了檔案中
這也可以同時定義標準錯誤和標準輸出重定向
[root@shell io_redirection]# cat test3.sh #!/bin/bash exec 1>testout.txt exec 2>testerr.txt echo "normal output 1" >&1 echo "normal output 2" >&1 echo "error output 1" >&2 echo "error output 2" >&2 [root@shell io_redirection]# bash test3.sh [root@shell io_redirection]# cat testerr.txt error output 1 error output 2 [root@shell io_redirection]# cat testout.txt normal output 1 normal output 2
指令碼中的輸入重定向
使用exec 0<檔名
可以實現指令碼中的輸入重定向。
[root@shell io_redirection]# cat input.sh #!/bin/bash exec 0< testerr.txt//使用exec實現輸入重定向,將testerr.txt作為輸入 count=1//定義一個變數count,用來遍歷testerr.txt while read line//迴圈遍歷輸入的每一行 do echo "line $count: $line"//輸出,"line 行號:每行內容" count=$[count+1]//count自增,實現遍歷每行 done [root@shell io_redirection]# bash input.sh //檢視輸出結果 line 1: error output 1 line 2: error output 2
管道
在shell中,將一個命令的輸出,重定向到另一個命名的輸入,就需要用到管道。資料通過管道在兩個命令中實現了傳遞。具體格式:
COMMAND1 | COMMAND2
ps -aux | less
就是將ps -aux的輸出,傳遞給less就可以實現分頁檢視
[root@shell io_redirection]# ps -axu | grep bash Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ root 1018 0.0 0.3 108304 1944 pts/0 Ss 21:47 0:00 -bash root 1033 0.0 0.3 108304 1896 pts/1 Ss+ 21:47 0:00 -bash root 1369 0.0 0.1 103244 832 pts/0 S+ 23:30 0:00 grep bash //將ps命令的輸出傳遞給grep命令,實現過濾出bash相關的程序資訊
如果我們使用
ps -aux > psfile
less < psfile
這樣也可以實現ps -aux | less的功能,但是這樣1,效率不高;2,核心開銷大
管道前後命令是同時進行的,不佔用檔案或者緩衝器,效能大大提高。
有沒有一個即可以輸出到終端,又實現重定向?即一個輸入,兩個輸出?
[root@shell io_redirection]# date |tee date.txt Tue Apr 10 23:35:06 EDT 2018 [root@shell io_redirection]# cat date.txt Tue Apr 10 23:35:06 EDT 2018
這就是tee
命令,tee
命令的實現是管道和檔案輸入輸出重定向的同時利用