一、Shell 輸入/輸出重定向
大多數 UNIX 系統命令從你的終端接受輸入并將所產生的輸出發送回??到您的終端。一個命令通常從一個叫標準輸入的地方讀取輸入,默認情況下,這恰好是你的終端。同樣,一個命令通常將其輸出寫入到標準輸出,默認情況下,這也是你的終端。
文件描述符(fd):文件描述符是一個非負整數,在打開現存文件或新建文件時,內核會返回一個文件描述符,讀寫文件也需要使用文件描述符來訪問文件。
內核為每個進程維護該進程打開的文件記錄表。文件描述符只適于 Unix、Linux 操作系統。
文件描述符 0 通常是標準輸入(STDIN),1 是標準輸出(STDOUT),2 是標準錯誤輸出(STDERR)。
二、重定向符號
輸入和輸出可以被重定向符號解釋到 shell。
shell 命令是從左到右依次執行命令。
> ?符號左邊輸出作為右邊輸入(標準輸出)
>> 符號左邊輸出追加右邊輸入
< ?符號右邊輸出作為左邊輸入(標準輸入)
<< 符號右邊輸出追加左邊輸入
& ?重定向綁定符號
1、重定向輸出
重定向一般通過在命令間插入特定的符號來實現。
實例:
執行下面的 who 命令,它將命令的完整的輸出重定向在用戶文件中(users):
$ who > users
執行后,并沒有在終端輸出信息,這是因為輸出已被從默認的標準輸出設備(終端)重定向到指定的文件。
你可以使用 cat 命令查看文件內容:
$ cat users
輸出重定向會覆蓋文件內容,請看下面的例子:
$ echo "username is john" > users
$ cat users
username is john
如果不希望文件內容被覆蓋,可以使用 >> 追加到文件末尾,例如:
$ echo "username is john" >> users
$ cat users
username is john
username is john
?
2、重定向輸入
一般格式:[n]<word
如果 n 沒有指定,默認是 0
示例:
a.txt 內容作為 grep 輸入:
# grep "test" --color < a.txt
實例:
接著以上實例,我們需要統計 users 文件的行數,執行以下命令:
$ wc -l users
? ? ? ?2 users
也可以將輸入重定向到 users 文件:
$ ?wc -l < users
? ? ? ?2 ?
?
三、重定向標準輸出和標準錯誤
1)覆蓋重定向標準輸出和標準錯誤
&>word 和>&word 等價于 >word 2>&1?
&將標準輸出和標準輸入綁定到一起,重定向 word 文件。
示例:
當不確定執行對錯時都覆蓋到文件:
# echo "1 + 1" |bc &> error.log
當不確定執行對錯時都覆蓋到文件:
# echo "1 + 1" |bc > error.log 2>&1
2)追加重定向標準輸出和標準錯誤
&>>word 等價于>>word 2>&1
示例:
當不確定執行對錯時都追加文件:
# echo "1 + 1" |bc &>> error.log
?
3)重定向操作符command << delimiter
shell將分界符delimiter之后直至下一個同樣的分界符之前的所有內容都作為輸入,遇到下一個分界符,shell就知道輸入結束了。
這一命令對于自動或遠程的例程非常有用。可以任意定義分界符delimiter,最常見的是EOF。
示例:自動登錄ftp下載文件
ftp -in 192.168.100.100 <<EOF
user test test
get 1.txt
bye
EOF
四、重定向到空設備
/dev/null 是一個空設備,向它寫入的數組都會丟棄,但返回狀態是成功的。與其對應的還有一個/dev/zero 設備,提供無限的 0 數據流。
在寫 Shell 腳本時我們經常會用到/dev/null 設備,將 stdout、stderr 輸出給它,也就是我們不想要這些輸出的數據。
通過重定向到/dev/null 忽略輸出,比如我們沒有安裝 bc 計算器,正常會拋出沒有發現命令:
# echo "1 + 1" |bc >/dev/null 2>&1
這就讓標準和錯誤輸出到了空設備。
忽略標準輸出:
# echo "test" >/dev/null
忽略錯誤輸出:
# echo "1 + 1" |bc 2>/dev/null
?
五、read 命令
read 命令從標準輸入讀取,并把輸入的內容復制給變量。
命令格式: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p?
prompt] [-t timeout] [-u fd] [name ...]
獲取用戶輸入保存到變量:
# read -p "Please input your name: " VAR
Please input your name: lizhenliang
用戶輸入保存為數組:
# read -p "Please input your name: " -a ARRAY
Please input your name: a b c
# echo ${ARRAY[*]}
a b c
遇到 e 字符返回:
# read -d e VAR
123
456
e
# echo $VAR
123 456
?
從文件作為 read 標準輸入: # cat a.txt adfasfd # read VAR < a.txt # echo $VAR adfasfd while 循環讀取每一行作為 read 的標準輸入: # cat a.txt |while read LINE; do echo $LINE; done 123 abc 分別變量賦值: # read a b c 1 2 3 # echo $a 1 # echo $b 2 # echo $c 3