Linux shell 学习笔记(11)— 理解输入和输出(标准输入、输出、错误以及临时重定向和永久重定向)
1. 理解輸入和輸出
1.1 標準文件描述符
Linux 系統(tǒng)將每個對象當(dāng)作文件處理。這包括輸入和輸出進程。Linux 用文件描述符(file descriptor)來標識每個文件對象。文件描述符是一個非負整數(shù),可以唯一標識會話中打開的文件。每個進程一次最多可以有九個文件描述符。Linux 標準文件描述符如下:
| 文件描述符 | 縮寫 | 描述 |
|---|---|---|
| 0 | STDIN | 標準輸入 |
| 1 | STDOUT | 標準輸出 |
| 2 | STDERR | 標準結(jié)果 |
-
STDIN
STDIN 文件描述符代表 shell 的標準輸入。對終端界面來說,標準輸入是鍵盤。shell 從 STDIN 文件描述符對應(yīng)的鍵盤獲得輸入,在用戶輸入時處理每個字符。
在使用輸入重定向符號(<)時,Linux 會用重定向指定的文件來替換標準輸入文件描述符。它會讀取文件并提取數(shù)據(jù),就如同它是鍵盤上鍵入的。可以通過 STDIN 重定向符號強制 cat 命令接受來自另一個非 STDIN 文件的輸入。
$ cat < testfile This is the first line. This is the second line. This is the third line. $現(xiàn)在 cat 命令會用 testfile 文件中的行作為輸入。
-
STDOUT
STDOUT 文件描述符代表 shell 的標準輸出。在終端界面上,標準輸出就是終端顯示器。shell 的所有輸出(包括 shell 中運行的程序和腳本)會被定向到標準輸出中,也就是顯示器。
$ ls -l > test2 $ cat test2 total 20 -rw-rw-r-- 1 rich rich 53 2014-10-16 11:30 test -rw-rw-r-- 1 rich rich 0 2014-10-16 11:32 test2 -rw-rw-r-- 1 rich rich 73 2014-10-16 11:23 testfile $通過輸出重定向符號,通常會顯示到顯示器的所有輸出會被 shell 重定向到指定的重定向文件。
可以將數(shù)據(jù)追加到某個文件。這可以用>>符號來完成。
$ who >> test2 $ cat test2 total 20 -rw-rw-r-- 1 rich rich 53 2014-10-16 11:30 test -rw-rw-r-- 1 rich rich 0 2014-10-16 11:32 test2 -rw-rw-r-- 1 rich rich 73 2014-10-16 11:23 testfile rich pts/0 2014-10-17 15:34 (192.168.1.2) $shell 對于錯誤消息的處理是跟普通輸出分開的。
$ ls -al badfile > test3 ls: cannot access badfile: No such file or directory $ cat test3 $?
-
STDERR
shell 通過特殊的 STDERR 文件描述符來處理錯誤消息。STDERR 文件描述符代表 shell 的標準錯誤輸出。shell 或 shell 中運行的程序和腳本出錯時生成的錯誤消息都會發(fā)送到這個位置。
默認情況下,STDERR 文件描述符會和 STDOUT 文件描述符指向同樣的地方(盡管分配給它們的文件描述符值不同)。也就是說,默認情況下,錯誤消息也會輸出到顯示器輸出中。
但如上例,STDERR 并不會隨著 STDOUT 的重定向而發(fā)生改變。
1.2 重定向錯誤
-
只重定向錯誤
STDERR 文件描述符被設(shè)成 2。可以選擇只重定向錯誤消息,將該文件描述符值放在重定向符號前。該值必須緊緊地放在重定向符號前,否則不會工作。
$ ls -al badfile 2> test4 $ cat test4 ls: cannot access badfile: No such file or directory $?
-
重定向錯誤和數(shù)據(jù)
如果想重定向錯誤和正常輸出,必須用兩個重定向符號。需要在符號前面放上待重定向數(shù)據(jù)所對應(yīng)的文件描述符,然后指向用于保存數(shù)據(jù)的輸出文件。
$ ls -al test test2 test3 badtest 2> test6 1> test7 $ cat test6 ls: cannot access test: No such file or directory ls: cannot access badtest: No such file or directory $ cat test7 -rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2 -rw-rw-r-- 1 rich rich 0 2014-10-16 11:33 test3 $shell 利用 1> 符號將 ls 命令的正常輸出重定向到了 test7 文件,而這些輸出本該是進入 STDOUT 的。所有本該輸出到 STDERR 的錯誤消息通過 2> 符號被重定向到了 test6 文件。
也可以將 STDERR 和 STDOUT 的輸出重定向到同一個輸出文件。為此 bash shell 提供了特殊的重定向符號 &>。
$ ls -al test test2 test3 badtest &> test7 $ cat test7 ls: cannot access test: No such file or directory ls: cannot access badtest: No such file or directory -rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2 -rw-rw-r-- 1 rich rich 0 2014-10-16 11:33 test3 $當(dāng)使用 &> 符時,命令生成的所有輸出都會發(fā)送到同一位置,包括數(shù)據(jù)和錯誤。
2. 在腳本中重定向輸出
2.1 臨時重定向
在重定向到文件描述符時,你必須在文件描述符數(shù)字之前加一個 &:
echo "This is an error message" >&2
這行會在腳本的 STDERR 文件描述符所指向的位置顯示文本,而不是通常的 STDOUT。
$ cat test8
#!/bin/bash
# testing STDERR messages
echo "This is an error" >&2
echo "This is normal output"
$
像平常一樣運行這個腳本,你可能看不出什么區(qū)別。
$ ./test8
This is an error
This is normal output
$
默認情況下,Linux 會將 STDERR 導(dǎo)向 STDOUT。但是,如果你在運行腳本時重定向了STDERR,腳本中所有導(dǎo)向 STDERR 的文本都會被重定向。
$ ./test8 2> test9
This is normal output
$ cat test9
This is an error
$
2.2 永久重定向
如果腳本中有大量數(shù)據(jù)需要重定向,那重定向每個 echo 語句就會很煩瑣。取而代之,你可以用exec 命令告訴 shell 在腳本執(zhí)行期間重定向某個特定文件描述符。
$ cat test10
#!/bin/bash
# redirecting all output to a file
exec 1>testout
echo "This is a test of redirecting all output"
echo "from a script to another file."
echo "without having to redirect every individual line"
$ ./test10
$ cat testout
This is a test of redirecting all output
from a script to another file.
without having to redirect every individual line
$
exec 命令會啟動一個新 shell 并將 STDOUT 文件描述符重定向到文件。腳本中發(fā)給 STDOUT 的所有輸出會被重定向到文件。
$ cat test11
#!/bin/bash
# redirecting output to different locations
exec 2>testerror
echo "This is the start of the script"
echo "now redirecting all output to another location"
exec 1>testout
echo "This output should go to the testout file"
echo "but this should go to the testerror file" >&2
$
$ ./test11
This is the start of the script
now redirecting all output to another location
$ cat testout
This output should go to the testout file
$ cat testerror
but this should go to the testerror file
$
2.3 在腳本中重定向輸入
exec 命令允許你將 STDIN 重定向到Linux 系統(tǒng)上的文件中:exec 0< testfile
$ cat test12
#!/bin/bash
# redirecting file input
exec 0< testfile
count=1
while read line
do
echo "Line #$count: $line"
count=$[ $count + 1 ]
done
$ ./test12
Line #1: This is the first line.
Line #2: This is the second line.
Line #3: This is the third line.
$
4. 創(chuàng)建自己的重定向
待補充
5. 阻止命令輸出
可以將 STDERR 重定向到一個叫作 null 文件的特殊文件。null 文件跟它的名字很像,文件里什么都沒有。shell 輸出到 null 文件的任何數(shù)據(jù)都不會保存,全部都被丟掉了。
在 Linux 系統(tǒng)上 null 文件的標準位置是 /dev/null。你重定向到該位置的任何數(shù)據(jù)都會被丟掉,不會顯示。
$ ls -al > /dev/null
$ cat /dev/null
$
也可以在輸入重定向中將 /dev/null 作為輸入文件。由于 /dev/null 文件不含有任何內(nèi)容,程序員通常用它來快速清除現(xiàn)有文件中的數(shù)據(jù),而不用先刪除文件再重新創(chuàng)建。
$ cat testfile
This is the first line.
This is the second line.
This is the third line.
$ cat /dev/null > testfile
$ cat testfile
$
總結(jié)
以上是生活随笔為你收集整理的Linux shell 学习笔记(11)— 理解输入和输出(标准输入、输出、错误以及临时重定向和永久重定向)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux shell 学习笔记(10)
- 下一篇: Linux shell 学习笔记(12)