十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
一個(gè)進(jìn)程默認(rèn)會打開標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、錯(cuò)誤輸出三個(gè)文件描述符
成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供嵩明企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、HTML5建站、小程序制作等業(yè)務(wù)。10年已為嵩明眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。
文件描述符為0,小于號表示數(shù)據(jù)由文件流入命令
usage:
命令 file
#加入輸入重定向,對輸入文件進(jìn)行計(jì)數(shù)
wc -l /etc/passwd
文件描述符為1,大于號表述數(shù)據(jù)由命令流入文件
所以: echo "hello" t.log 也可以寫成 echo "hello" 1 t.log
會把文件的內(nèi)容清空,再輸入到新的文件
會把當(dāng)前內(nèi)容保持不變,然后在下一行進(jìn)行追加
2 錯(cuò)誤重定向,如果當(dāng)前命令產(chǎn)生了錯(cuò)誤,會把錯(cuò)誤重定向到文件中,而不會打印到屏幕
無論內(nèi)容正確還是錯(cuò)誤都會把文件輸出到文件中。
stderr的文件描述符為2,Unix程序會向stderr流中寫入錯(cuò)誤信息。
默認(rèn)情況下, command file 將stdout 重定向到 file, command file 將stdin 重定向到 file。
如果希望 stderr 重定向到 file,可以這樣寫:
$ command 2file
如果希望 stderr 追加到 file 文件末尾,可以這樣寫:
$ command 2file 2 表示標(biāo)準(zhǔn)錯(cuò)誤文件(stderr)
如果希望將 stdout 和 stderr 合并后重定向到 file,可以這樣寫:
$ command file 21 或者 $ command file 21
如果希望對 stdin 和 stdout 都重定向,可以這樣寫:
$ command file1 file2
command 命令將 stdin 重定向到 file1,將 stdout 重定向到 file2。
含義:將標(biāo)準(zhǔn)錯(cuò)誤輸出 重定向到 標(biāo)準(zhǔn)輸出。
符號是一個(gè)整體,不可分開,分開后就不是上述含義了。
比如有些人可能會這么想:2是標(biāo)準(zhǔn)錯(cuò)誤輸入,1是標(biāo)準(zhǔn)輸出,是重定向符號,那么"將標(biāo)準(zhǔn)錯(cuò)誤輸出重定向到標(biāo)準(zhǔn)輸出"是不是就應(yīng)該寫成"21"就行了?是這樣嗎? 如果是嘗試過,你就知道21的寫法其實(shí)是將標(biāo)準(zhǔn)錯(cuò)誤輸出重定向到名為"1"的文件里去了
關(guān)于linux bash的重定向
所謂I/O重定向簡單來說就是一個(gè)過程,這個(gè)過程捕捉一個(gè)文件,或者命令,程序,腳本,甚至腳本中的代碼塊(code block)的輸出,然后把捕捉到的輸出,作為輸入發(fā)送給另外一個(gè)文件,命令,程序,或者腳本。
如果談到I/O重定向,就涉及到文件標(biāo)識符(File Descriptor)的概念, 在Linux系統(tǒng)中,系統(tǒng)為每一個(gè)打開的文件指定一個(gè)文件標(biāo)識符以便系統(tǒng)對文件進(jìn)行跟蹤,這里有些和C語言編程里的文件句柄相似,文件標(biāo)識符是一個(gè)數(shù)字,不同數(shù)字代表不同的含義,默認(rèn)情況下,系統(tǒng)占用了3個(gè),分別是0標(biāo)準(zhǔn)輸入(stdin),1標(biāo)準(zhǔn)輸出(stdout), 2標(biāo)準(zhǔn)錯(cuò)誤(stderr), 另外3-9是保留的標(biāo)識符,可以把這些標(biāo)識符指定成標(biāo)準(zhǔn)輸入,輸出或者錯(cuò)誤作為臨時(shí)連接。通常這樣可以解決很多復(fù)雜的重定向請求。
標(biāo)準(zhǔn)輸入通常指鍵盤的輸入
標(biāo)準(zhǔn)輸出通常指顯示器的輸出
標(biāo)準(zhǔn)錯(cuò)誤通常也是定向到顯示器
請看以下例子,來描述一下他們的關(guān)系
#ls /dev
這個(gè)命令列出/dev目錄下的所有文件,在屏幕上輸出結(jié)果。
這里 /dev 就是作為命令ls的標(biāo)準(zhǔn)輸入(從鍵盤輸入),而打印在屏幕的結(jié)果就是標(biāo)準(zhǔn)輸出(/dev目錄中的內(nèi)容)
還是回到標(biāo)題,重定向就是把標(biāo)準(zhǔn)的`輸入或者輸出更改成其他的方式,請參看如下例子
或者等同于
#ls /dev 1filename #注意:"1"和""中間沒有空格
以上命令會把命令的標(biāo)準(zhǔn)輸出重新定向到一個(gè)文件filename,而不是顯示到屏幕上,如果不指明文件標(biāo)識符,系統(tǒng)默認(rèn)的就是1, 因此1可以省略
如果把上面例子重的""改成""則表示把輸出追加到filename文件的末尾,如果文件不存在則創(chuàng)建它。如下
#ls /dev filename
也可以把標(biāo)準(zhǔn)錯(cuò)誤重新定向到文件
#ls -qw /dev 2filename
顯然 -qw是一個(gè)錯(cuò)誤參數(shù),通常會在顯示器上報(bào)告一個(gè)錯(cuò)誤信息,但由于把2標(biāo)準(zhǔn)錯(cuò)誤(stderr)重新定向到了文件filename,因此顯示器沒有錯(cuò)誤信息,而信息寫到了文件里面
以下命令是把標(biāo)準(zhǔn)輸出和錯(cuò)誤都定向到文件
#ls /dev filename
""在這里代表標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤,這里無論是正常輸出還是錯(cuò)誤信息都寫到filename中了。
重新定義標(biāo)準(zhǔn)輸入,輸出,和錯(cuò)誤的文件標(biāo)識符
重新定義文件標(biāo)識符可以用ij命令,表示把文件標(biāo)識符i重新定向到j(luò),你可以把""理解為"取地址"
請看以下例子
#exec 51
表示把文件標(biāo)識符5定向到標(biāo)準(zhǔn)輸出,這個(gè)命令通常用來臨時(shí)保存標(biāo)準(zhǔn)輸入。
同樣標(biāo)準(zhǔn)輸入也是可以重新定向的,請參考下面例子
# grep search-word
一般來說grep命令在給定文件中搜索字符串,以上命令把文件filename作為grep命令的標(biāo)準(zhǔn)輸入,而不是從鍵盤輸入。
前面曾經(jīng)提到,系統(tǒng)為每一個(gè)打開的文件指定一個(gè)文件標(biāo)識符以便系統(tǒng)對文件進(jìn)行跟蹤,那么默認(rèn)的文件標(biāo)識符是什么呢?答案是0,也就是標(biāo)準(zhǔn)輸入,或者可以說從鍵盤輸入。當(dāng)然這個(gè)文件標(biāo)識符也可以自己指定,請參考下面例子
#echo 123456789 filename 把字符串寫到文件filename中 #exec 3filename 把文件filename打開,并指定文件標(biāo)識符為3 #read -n 4 3 從文件中讀4個(gè)字符,句柄已經(jīng)指到第四個(gè)字符末尾 #echo -n . 3 在第5個(gè)字符處寫一個(gè)點(diǎn),覆蓋第5個(gè)字符,-n表示不換行 #exec 3- 關(guān)閉文件標(biāo)識符3
現(xiàn)在cat filename文件的結(jié)果就成了1234.6789
命令jfilename表示把文件打開,并指明文件標(biāo)識符為j
"-"表示關(guān)閉文件標(biāo)識符
有關(guān)關(guān)閉文件標(biāo)識符的操作請參考下面
n- 關(guān)閉輸入文件標(biāo)識符n 0-或- 關(guān)閉標(biāo)準(zhǔn)輸入stdin n- 關(guān)閉輸出文件標(biāo)識符n 1-或-關(guān)閉標(biāo)準(zhǔn)輸出stdout
另外還有一些其他命令,如下參考
2. : filename 或者 filename
表示把文件filename設(shè)置成空,也就是清空文件內(nèi)容,如果文件不存在,則創(chuàng)建一個(gè)空文件,(等同于touch命令) :表示一個(gè)空輸出,兩個(gè)命令的唯一區(qū)別就是filename不是在所有shell都可以正常工作的。
;
重定向能夠?qū)崿F(xiàn)Linux命令的輸入輸出與文件之間重定向,以及實(shí)現(xiàn)將多個(gè)命令組合起來實(shí)現(xiàn)更加強(qiáng)大的命令。這部分涉及到的比較多的命令主要有:
cat:連接文件 ? ? ? ? ?sort:排序文本行 ? ? ? uniq:忽略或者報(bào)告重復(fù)行
wc:統(tǒng)計(jì)文件的行數(shù)、詞數(shù)、字節(jié)數(shù)
grep:打印匹配制定模式的行
head:輸出文件的頭部 ? ? ? ? ? ? ? tail:輸出文件的尾部
tee:從標(biāo)準(zhǔn)輸入讀,并往標(biāo)準(zhǔn)輸出或者文件寫
重定向標(biāo)準(zhǔn)輸出
使用可以將本來出現(xiàn)在屏幕的標(biāo)準(zhǔn)輸出信息重定向到一個(gè)文件中。
使用可以在實(shí)現(xiàn)重定向時(shí)不覆蓋原有內(nèi)容,而是在文件末尾追加內(nèi)容。
重定向標(biāo)準(zhǔn)錯(cuò)誤信息到文件
使用文件描述符,在shell中,默認(rèn)用數(shù)字0,1,2分別代表標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)錯(cuò)誤。
屏蔽不想看到的信息
Linux中有一個(gè)特殊的文件/dev/null,這個(gè)文件叫做bit bucket,可以接受輸入信息但是什么都不做。例如:ls?/usr/? /dev/null
重定向標(biāo)準(zhǔn)輸入
cat命令可以接受一組文件為參數(shù),將這些文件復(fù)制到標(biāo)準(zhǔn)輸出。我們前面的例子中已經(jīng)多次使用到cat命令來將文本文件的內(nèi)容讀取到屏幕上。cat還有一個(gè)很重要的功能:接受一組文件,然后通過重定向?qū)⑺麄冎匦陆M合到一個(gè)文件中。
cat ls1 ls2 ls這個(gè)命令將ls1和ls2文件中的內(nèi)容合并到ls文件中了。cat命令的這種功能不僅僅適用于文本文件,同樣對二進(jìn)制文件有效。這個(gè)場景主要在將多個(gè)壓縮包文件合并到一個(gè)壓縮包中用到。
cat也可以不傳遞參數(shù),這種情況下,cat會重定向標(biāo)準(zhǔn)輸入到標(biāo)準(zhǔn)輸出。
管道
Linux提供|操作符,該操作符可以將一個(gè)命令的輸出作為另一個(gè)命令的輸入,這樣通過多個(gè)命令的協(xié)作來完成一些比較復(fù)雜的內(nèi)容。比如,我們可以通過uniq命令來排除重復(fù)的行。但是uniq命令往往需要和sort命令配合使用。因?yàn)閡niq接收一組排好序的文本,而剛好sort可以將文本行排序。
用途:不掛斷地運(yùn)行命令。
語法:nohup Command [ Arg … ] [ ]
無論是否將 nohup 命令的輸出重定向到終端,輸出都將附加到當(dāng)前目錄的 nohup.out 文件中。
如果當(dāng)前目錄的 nohup.out 文件不可寫,輸出重定向到 $HOME/nohup.out 文件中。
如果沒有文件能創(chuàng)建或打開以用于追加,那么 Command 參數(shù)指定的命令不可調(diào)用。
退出狀態(tài):該命令返回下列出口值:
126 可以查找但不能調(diào)用 Command 參數(shù)指定的命令。
127 nohup 命令發(fā)生錯(cuò)誤或不能查找由 Command 參數(shù)指定的命令。
否則,nohup 命令的退出狀態(tài)是 Command 參數(shù)指定命令的退出狀態(tài)。
用途:在后臺運(yùn)行
一般兩個(gè)一起用
3.為什么呢 21 要寫在后面?
首先是command file將標(biāo)準(zhǔn)輸出重定向到file中, 21 是標(biāo)準(zhǔn)錯(cuò)誤拷貝了標(biāo)準(zhǔn)輸出的行為,也就是同樣被重定向到file中,最終結(jié)果就是標(biāo)準(zhǔn)輸出和錯(cuò)誤都被重定向到file中。
21 標(biāo)準(zhǔn)錯(cuò)誤拷貝了標(biāo)準(zhǔn)輸出的行為,但此時(shí)標(biāo)準(zhǔn)輸出還是在終端。file 后輸出才被重定向到file,但標(biāo)準(zhǔn)錯(cuò)誤仍然保持在終端。
用strace可以看到:
這個(gè)命令中實(shí)現(xiàn)重定向的關(guān)鍵系統(tǒng)調(diào)用序列是:
open(file) == 3
dup2(3,1)
dup2(1,2)
這個(gè)命令中實(shí)現(xiàn)重定向的關(guān)鍵系統(tǒng)調(diào)用序列是:
dup2(1,2)
open(file) == 3
dup2(3,1)
注意:0 是標(biāo)準(zhǔn)輸入(STDIN),1 是標(biāo)準(zhǔn)輸出(STDOUT),2 是標(biāo)準(zhǔn)錯(cuò)誤輸出(STDERR)。
這里的2和之間不可以有空格,2是一體的時(shí)候才表示錯(cuò)誤輸出。