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