您可以通過(guò)兩種方式顯示shell腳本的輸出,在屏幕上顯示輸出或者將輸出發(fā)送到文件。
在本教程中我們說(shuō)明Shell腳本中必不可少的知識(shí),即標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和重定向。
在Linux 一切都是文件,包括輸入和輸出。每個(gè)進(jìn)程都可以同時(shí)打開(kāi)九個(gè)文件描述符。保留的文件描述符0、1、2提供shell進(jìn)程使用。
0
表示標(biāo)準(zhǔn)輸入。1
表示標(biāo)準(zhǔn)輸出。2
標(biāo)準(zhǔn)錯(cuò)誤。您可以使用這些文件描述符來(lái)控制程序或者腳本的輸入和輸出。
您需要完全理解這三個(gè)概念,因?yàn)樗荢hell腳本或者程序的支柱。因此,我們將詳細(xì)描述它們中的每一個(gè)。
標(biāo)準(zhǔn)輸入
STDIN
代表標(biāo)準(zhǔn)輸入,也就是文件描述符1
,默認(rèn)為鍵盤(pán)。您可以使用重定向符號(hào)<
將指定文件作為標(biāo)準(zhǔn)輸入。
如果你將標(biāo)準(zhǔn)輸入替換為文件,重定向符號(hào)<
會(huì)將的文件數(shù)據(jù)作為標(biāo)準(zhǔn)輸入傳遞給指定的程序。
例如命令cat < archive.tar | gzip -c > archive.tar.gz
使用重定向符號(hào)<
將archive.tar
文件作為標(biāo)準(zhǔn)輸入傳遞給cat命令。
cat命令接收標(biāo)準(zhǔn)輸入后,又將archive.tar
文件內(nèi)容寫(xiě)入標(biāo)準(zhǔn)輸出,最后通過(guò)管道傳遞給gzip命令進(jìn)行壓縮。
cat < archive.tar | gzip -c > archive.tar.gz
標(biāo)準(zhǔn)輸出
STDOUT
代表標(biāo)準(zhǔn)輸出,也就是文件描述符2
,默認(rèn)為屏幕。您可以使用重定向符號(hào)>>
,>
將標(biāo)準(zhǔn)輸出重定向到文件。
您可以使用重定向符號(hào)>>
將數(shù)據(jù)追加到指定文件。例如命令pwd >> log
會(huì)將pwd
命令的標(biāo)準(zhǔn)輸出追加到文件log。
而重定向符號(hào)>
則會(huì)使用標(biāo)準(zhǔn)輸出覆蓋指定文件。例如命令> filename
將會(huì)清空文件filename
。
pwd >> log
> filename
標(biāo)準(zhǔn)錯(cuò)誤
ls file2 > file
命令嘗試使用重定向>
符號(hào)將標(biāo)準(zhǔn)輸出重定向到文件。如果你的計(jì)算機(jī)沒(méi)有xfile文件。
ls
命令將會(huì)打印一個(gè)錯(cuò)誤ls: cannot access 'file2': No such file or directory
,這通常稱(chēng)為標(biāo)準(zhǔn)錯(cuò)誤STDERR
。
默認(rèn)情況下,Shell將標(biāo)準(zhǔn)錯(cuò)誤發(fā)送到屏幕。如果您需要將標(biāo)準(zhǔn)錯(cuò)誤重定向到日志文件,可以使用重定向符號(hào)>
/>>
重定向錯(cuò)誤。
ls file2 > file
ls: cannot access 'file2': No such file or directory
重定向錯(cuò)誤
正如引言所提到文件描述符2
是標(biāo)準(zhǔn)錯(cuò)誤,因此我們將文件描述符2
放在重定向符號(hào)之前來(lái)重定向錯(cuò)誤。
假設(shè)當(dāng)前目錄不存在文件xfile,現(xiàn)在運(yùn)行ls -l xfile 2> log
命令將會(huì)把錯(cuò)誤重定向到文件log,2>
表示重定向標(biāo)準(zhǔn)錯(cuò)誤。
如您所見(jiàn)錯(cuò)誤消息并沒(méi)有打印在屏幕,而是寫(xiě)入到文件,你可以運(yùn)行cat命令查看文log
文件內(nèi)容。
ls -l xfile 2> log
重定向錯(cuò)誤與標(biāo)準(zhǔn)輸出
要重定向錯(cuò)誤和標(biāo)準(zhǔn)輸出,您必須在每個(gè)重定向符號(hào)之前添加正確的文件描述符。在同一命令可以使用多個(gè)重定向符號(hào)來(lái)實(shí)現(xiàn)標(biāo)準(zhǔn)錯(cuò)誤和標(biāo)準(zhǔn)錯(cuò)誤的重定向。
假設(shè)當(dāng)前目錄存在文件file1,但不存在文件file2?,F(xiàn)在運(yùn)行命令ls flie1 file2
將會(huì)同時(shí)產(chǎn)生標(biāo)準(zhǔn)錯(cuò)誤和標(biāo)準(zhǔn)輸出。
出于某種原因,你可能需要標(biāo)準(zhǔn)錯(cuò)誤寫(xiě)入到文件error.log,而標(biāo)準(zhǔn)輸出寫(xiě)入文件access.log。
此時(shí)你就可以使用文件描述1
和重定向符號(hào)>
寫(xiě)入到access.log
文件,組合之后的符號(hào)是1>
。
使用文件描述符2
和重定向符好>
送到寫(xiě)入到error.log文件,組合之后的符號(hào)是2>
。因此最終的命令是ls file1 file2 2> error.log 1> access.log
。
除此之外您還可以使用&>
符號(hào)將標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤重定向到同一個(gè)文件。例如命令ls file1 file2 &> log
。
ls file1 file2 2> error.log 1> access.log
ls file1 file2 &> log
永久重定向
輸出重定向有兩種方式臨時(shí)重定向和永久重定向。對(duì)于 臨時(shí)重定向 ,您可以使用>
或者>>
符號(hào)。如果您有很多數(shù)據(jù)需要重定向,您可以使用exec
命令進(jìn)行永久重定向。
永久重定向并不是真的就一直唯一類(lèi)型的重定向,可以隨時(shí)使用exec
命令進(jìn)行修改。
永久重定向相當(dāng)于為進(jìn)程創(chuàng)建一個(gè)文件描述符,接下來(lái)運(yùn)行命令的標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯(cuò)誤,標(biāo)準(zhǔn)輸入都使用同一文件描述符。
例如std.sh
腳本將會(huì)重定向exec
命令之后的所有標(biāo)準(zhǔn)輸出,也就是echo生成的標(biāo)準(zhǔn)輸出。如果運(yùn)行cat命令查看log文件,我們將看到echo命令的標(biāo)準(zhǔn)輸出。
你可以多次使用exec
命令多次重定向不同的文件描述符,例如命令exec 2> error.log
將標(biāo)準(zhǔn)錯(cuò)誤重定向到文件error.log
。
std.sh
#!/bin/bash
exec 1> log #永久重定向標(biāo)準(zhǔn)輸出
echo "Permanent redirection"
echo "from a shell to a file."
echo "without redirecting every line"
exec 2> error.log #永久重定向標(biāo)準(zhǔn)錯(cuò)誤
echo "Script Begining ..."
echo "Redirecting Output"
除了使用exec
命令重定向標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯(cuò)誤。你還可以使用exec
命令重定向標(biāo)準(zhǔn)輸入。默認(rèn)的標(biāo)準(zhǔn)輸入STDIN
,也就是文件描述符1
,通常是鍵盤(pán)。
命令exec 0< log
將使用log文件作為標(biāo)準(zhǔn)輸入STDIN
,而不是默認(rèn)的鍵盤(pán)。通常Linux系統(tǒng)管理員使用這種技術(shù)來(lái)讀取日志文件進(jìn)行處理。
stdin.sh
腳本很簡(jiǎn)單。您應(yīng)該知道如何使用read 命令獲取用戶(hù)輸入。如果將文件重定向到標(biāo)準(zhǔn)輸入STDIN
,read命令將嘗試讀取文件的內(nèi)容。
stdin.sh
#!/bin/bash
exec 0< testfile
total=1
while read line; do
echo "#$total: $line"
total=$(($total + 1))
done
nohup命令重定向標(biāo)準(zhǔn)錯(cuò)誤和標(biāo)準(zhǔn)輸出
有時(shí)候您可能不想看到任何輸出。我們將輸出重定向到黑洞,也就是空設(shè)備文件/dev/null。這種情況在使用nohup命令啟動(dòng)后臺(tái)進(jìn)程時(shí)常見(jiàn)。
在使用nohup命令啟動(dòng)后臺(tái)進(jìn)程時(shí)你可能見(jiàn)過(guò)符號(hào)2>&1
,但很少使用這種方式2> /dev/null 1> /dev/null
重定向到空設(shè)備文件/dev/null
。
其實(shí)ls -al file1 file2 2> /dev/null 1> /dev/null
和ls -al file1 file2 > /dev/null 2>&1
是不相等的命令。
2> /dev/null 1> /dev/null
是直接將標(biāo)準(zhǔn)錯(cuò)誤重定向到空設(shè)備文件,而> /dev/null 2>&1
是將標(biāo)準(zhǔn)錯(cuò)誤先重定向到標(biāo)準(zhǔn)輸出,然后再重定向到空設(shè)備文件。
ls -al file1 file2 2> /dev/null 1> /dev/null
ls -al file1 file2 > /dev/null 2>&1
如果2>&1
是將標(biāo)準(zhǔn)錯(cuò)誤信息重定向到標(biāo)準(zhǔn)輸出,你可能會(huì)想問(wèn)2>1
結(jié)果是什么,我們可以運(yùn)行命令ls -al file1 file2 2>1
來(lái)驗(yàn)證這一點(diǎn)。
運(yùn)行命令后你可能注意到當(dāng)前目錄存在文件1,運(yùn)行命令cat 1
你會(huì)發(fā)現(xiàn)標(biāo)準(zhǔn)錯(cuò)誤都寫(xiě)入文件1。
也就是說(shuō)2>1
會(huì)將標(biāo)準(zhǔn)錯(cuò)誤重定向到文件1里面,所以2>&1
中的&1
指標(biāo)準(zhǔn)輸出。
ls -al file1 file2 2>1
cat 1
ls: cannot access 'file2': No such file or directory
結(jié)論
現(xiàn)在您了解標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)錯(cuò)誤以及如何重定向它們。
-
Linux
+關(guān)注
關(guān)注
87文章
11335瀏覽量
210068 -
Shell
+關(guān)注
關(guān)注
1文章
366瀏覽量
23430 -
腳本
+關(guān)注
關(guān)注
1文章
391瀏覽量
14913
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論