read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] One line is read from the standard input, or from the file descriptor fd supplied as an argument to the -u option, and the first word is assigned to the first name, the second word to the second name, and so on, with leftover words and their intervening separators assigned to the last name. If there are fewer words read from the input stream than names, the remaining names are assigned empty values. The characters in IFS are used to split the line into words. The backslash character (\) may be used to remove any special meaning for the next character read and for line continuation. Options, if supplied, have the following meanings: 從標準輸入上讀取一行數據,或者從經過 -u 選項指定的文件描述符 fd 上讀取,而且按照順序,將讀取的第一個 word 賦值給第一個 name ,第二個 word 賦值給 name ,以此類推,對於剩餘的 words 和 word 之間的分隔符都被賦值到最後一個 name 上。若是從輸入流上讀取的 word 的數量少於給出 的 name 數量,則多出來的 names 將被自動賦值爲空值。IFS 中所包含的字符用於將整行字符拆分紅單獨的 word (換句話說也就是將 IFS 中包含的字符 從行數據中去除,IFS 中默認包含的字符爲空格、製表符和回車)。反斜線字符(\)能夠用於移除緊隨其後讀到的字符的任何特殊含義,還可用於行接續。 若提供了選項,則具備以下意義: -a aname The words are assigned to sequential indices of the array variable aname, starting at 0. aname is unset before any new values are assigned. Other name arguments are ignored. -d delim The first character of delim is used to terminate the input line, rather than newline. delim 的首字符被用於做爲輸入行數據的終止符,而不是換行符。 -e If the standard input is coming from a terminal, readline (see READLINE above) is used to obtain the line. Readline uses the current (or default, if line editing was not previously active) editing settings. -i text If readline is being used to read the line, text is placed into the editing buffer before editing begins. -n nchars read returns after reading nchars characters rather than waiting for a complete line of input, but honor a delimiter if fewer than nchars characters are read before the delimiter. -N nchars read returns after reading exactly nchars characters rather than waiting for a complete line of input, unless EOF is encountered or read times out. Delimiter characters encountered in the input are not treated specially and do not cause read to return until nchars characters are read. -p prompt Display prompt on standard error, without a trailing newline, before attempting to read any input. The prompt is displayed only if input is coming from a terminal. 在開始讀取任何輸入前,向標準出錯上顯示提示信息,而且不帶尾部換行符。該提示信息僅在輸入數據來自終端的時候才被顯示。 -r Backslash does not act as an escape character. The backslash is considered to be part of the line. In particular, a backslash-newline pair may not be used as a line continuation. 反斜線不做爲轉義字符起做用。反斜線被當作行數據的一部分。 特別值得注意的是,反斜線-換行 組合將不能做爲行接續來使用。 -s Silent mode. If input is coming from a terminal, characters are not echoed. 安靜模式。若是輸入來自終端,字符將不會被 echo 。 -t timeout Cause read to time out and return failure if a complete line of input is not read within timeout seconds. timeout may be a decimal number with a fractional portion following the decimal point. This option is only effective if read is reading input from a terminal, pipe, or other special file; it has no effect when reading from regular files. If timeout is 0, read returns success if input is available on the specified file descriptor, failure otherwise. The exit status is greater than 128 if the timeout is exceeded. -u fd Read input from file descriptor fd. 從文件 fd 讀取輸入數據。 If no names are supplied, the line read is assigned to the variable REPLY. The return code is zero, unless end-of-file is encountered, read times out (in which case the return code is greater than 128), or an invalid file descriptor is supplied as the argument to -u. 若是沒有 name 變量被指定,所讀取的行數據將被賦值給變量 REPLY 。除非遇到了文件結束符(EOF),或者發生讀取超時(此時返回值將大於 128),或者 經過 -u 指定了無效的文件描述符,其餘狀況返回值均爲 0 。
【read 測試】 html
測試文件以下[root@Betty Shell]# vi file -module( unique_name_test ) . -compile(export_all). %% @spec (Nibble::integer()) -> char() %% @doc Returns the character code corresponding to Nibble. %% %% Nibble must be >=0 and =<16. hex_digit(0) -> $0; hex_digit(1) -> $1; hex_digit(2) -> $2; hex_digit(3) -> $3; hex_digit(4) -> $4; hex_digit(5) -> $5; hex_digit(6) -> $6; hex_digit(7) -> $7; hex_digit(8) -> $8; hex_digit(9) -> $9; hex_digit(10) -> $A; hex_digit(11) -> $B; hex_digit(12) -> $C; hex_digit(13) -> $D; hex_digit(14) -> $E; hex_digit(15) -> $F.
[root@Betty Shell]# read -r line < file [root@Betty Shell]# echo $line -module( unique_name_test ) .這一行命令用到了 Bash 的內置命令 read,和輸入重定向操做符 < 。read 命令從標準輸入中讀取一行,並將內容保存到變量 line 中。在這裏,-r 選項保證讀入的內容是原始的內容,意味着反斜槓轉義的行爲不會發生。輸入重定向操做符 < file 打開並讀取文件 file ,而後將它做爲 read 命令的標準輸入。
[root@Betty Shell]# IFS= read -r line < file [root@Betty Shell]# echo $line -module( unique_name_test ) .IFS 的變化僅會影響當前的命令,這行命令能夠保證讀入原始的首行內容到變量 line 中,同時行首與行尾的空白字符被保留。
[root@Betty Shell]# while read -r line; do > echo "test $line"; > done < file test -module( unique_name_test ) . test test -compile(export_all). test test test %% @spec (Nibble::integer()) -> char() test %% @doc Returns the character code corresponding to Nibble. test %% test %% Nibble must be >=0 and =<16. test hex_digit(0) -> $0; test hex_digit(1) -> $1; test hex_digit(2) -> $2; test hex_digit(3) -> $3; test hex_digit(4) -> $4; test hex_digit(5) -> $5; test hex_digit(6) -> $6; test hex_digit(7) -> $7; test hex_digit(8) -> $8; test hex_digit(9) -> $9; test hex_digit(10) -> $A; test hex_digit(11) -> $B; test hex_digit(12) -> $C; test hex_digit(13) -> $D; test hex_digit(14) -> $E; test hex_digit(15) -> $F. test test [root@Betty Shell]#這是一種正確的讀取文件內容的作法,read 命令放在 while 循環中。當 read 命令遇到文件結尾時(EOF),它會返回一個正值,致使循環判斷失敗終止。
while read -r line; do echo $line; done < file而按照常規編程思惟,while 循環的斷定條件應該是不爲 0 則循環,彷佛這裏就出現了矛盾。
[root@Betty workspace]# touch abc.txt [root@Betty workspace]# cat abc.txt [root@Betty workspace]# read -r line < abc.txt [root@Betty workspace]# echo $? 1 [root@Betty workspace]# echo "1" >> abc.txt [root@Betty workspace]# cat abc.txt 1 [root@Betty workspace]# read -r line < abc.txt [root@Betty workspace]# echo $? 0結果證實,read 讀到文件結束時確實返回 1 ,而讀到內容時返回 0 。
while list; do list; done The while command continuously executes the do list as long as the last command in list returns an exit status of zero. The exit status of the while commands is the exit status of the last do list command executed, or zero if none was executed.哈哈,套用工藤新一的話「真相只有一個」~~
[root@Betty Shell]# while IFS= read -r line; do > echo "test $line"; > done < file test -module( unique_name_test ) . test test -compile(export_all). test test test %% @spec (Nibble::integer()) -> char() test %% @doc Returns the character code corresponding to Nibble. test %% test %% Nibble must be >=0 and =<16. test hex_digit(0) -> $0; test hex_digit(1) -> $1; test hex_digit(2) -> $2; test hex_digit(3) -> $3; test hex_digit(4) -> $4; test hex_digit(5) -> $5; test hex_digit(6) -> $6; test hex_digit(7) -> $7; test hex_digit(8) -> $8; test hex_digit(9) -> $9; test hex_digit(10) -> $A; test hex_digit(11) -> $B; test hex_digit(12) -> $C; test hex_digit(13) -> $D; test hex_digit(14) -> $E; test hex_digit(15) -> $F. test test [root@Betty Shell]#從上面能夠看出 < file 永遠是放在最後的,若是你不想將 < file 放在最後,能夠經過管道將文件的內容輸入到 while 循環中:
[root@Betty Shell]# cat file | while IFS= read -r line; do > echo "test $line"; > done test -module( unique_name_test ) . test test -compile(export_all). test test test %% @spec (Nibble::integer()) -> char() test %% @doc Returns the character code corresponding to Nibble. test %% test %% Nibble must be >=0 and =<16. test hex_digit(0) -> $0; test hex_digit(1) -> $1; test hex_digit(2) -> $2; test hex_digit(3) -> $3; test hex_digit(4) -> $4; test hex_digit(5) -> $5; test hex_digit(6) -> $6; test hex_digit(7) -> $7; test hex_digit(8) -> $8; test hex_digit(9) -> $9; test hex_digit(10) -> $A; test hex_digit(11) -> $B; test hex_digit(12) -> $C; test hex_digit(13) -> $D; test hex_digit(14) -> $E; test hex_digit(15) -> $F. test test [root@Betty Shell]#
[root@Betty Shell]# head -1 file | while read -r field1 field2 field3 throwaway; do echo "filed1 = $field1";echo "field2 = $field2";echo "field3 = $field3"; done filed1 = -module( field2 = unique_name_test field3 = )若是在 read 命令中指定多個變量名,它會將讀入的內容分隔成多個字段,而後依次賦值給對應的變量,第一個字段賦值給第一個變量,第二個字段賦值給第二個變量,等等,最後將剩餘的全部字段賦值給最後一個變量。這也是爲何,在上面的例子中,咱們加了一個 throwaway 變量,不然的話,當文件的一行大於三個字段時,第三個變量的內容會包含全部剩餘的字段。
[root@Betty Shell]# head -1 file | while read -r field1 field2 field3 _; do echo "filed1 = $field1";echo "field2 = $field2";echo "field3 = $field3"; done filed1 = -module( field2 = unique_name_test field3 = )又或者,若是你的文件確實只有三個字段,能夠忽略 _ 。
cat > test.cfg <<EOF log_facility=daemon pid_file=/var/run/nrpe.pid EOF
cat > test.cfg <<ABC log_facility=daemon pid_file=/var/run/nrpe.pid ABC
cat <<ABC > test.cfg log_facility=daemon pid_file=/var/run/nrpe.pid ABC
[root@Betty Shell]# tr a-z A-Z << END_TEXT > one two three > uno dos tres > END_TEXTThis yields the output:
ONE TWO THREE UNO DOS TRES此處使用 <<END_TEXT 或 << END_TEXT 都正確。
[root@Betty Shell]# tr a-z A-Z <<- END_TEXT >(Ctrl-V + TAB)one two three >(Ctrl-V + TAB)uno dos tres >(Ctrl-V + TAB)END_TEXTThis yields the same output, notably not indented:
ONE TWO THREE UNO DOS TRES(
[root@Betty Shell]# tr a-z A-Z << END_TEXT >(Ctrl-V + TAB)one two three >(Ctrl-V + TAB)uno dos tres >(Ctrl-V + TAB)END_TEXT > END_TEXT將獲得
(Ctrl-V + TAB)ONE TWO THREE (Ctrl-V + TAB)UNO DOS TRES (Ctrl-V + TAB)END_TEXT)
[root@Betty Shell]# cat << EOF > Working dir $PWD > EOFyields:
Working dir /root/workspace/CODE_TEST/Shell上述行爲能夠經過引號引用標籤的任何部分進行取消。例如,將 EOF 使用單引號或者雙引號進行包含:
[root@Betty Shell]# cat << "EOF" > Working dir $PWD > EOFyields:
Working dir $PWD(
[root@Betty Shell]# cat << "E"OF Working dir $PWD EOF將獲得
Working dir $PWD)
[root@Betty Shell]# sql=$(cat <<EOF > SELECT foo, bar FROM db > WHERE foo='baz' > EOF > ) [root@Betty Shell]# [root@Betty Shell]# echo $sql SELECT foo, bar FROM db WHERE foo='baz' [root@Betty Shell]# [root@Betty Shell]# echo -e $sql -e enable interpretation of backslash escapes SELECT foo, bar FROM db WHERE foo='baz' [root@Betty Shell]# [root@Betty Shell]# echo -E $sql -E disable interpretation of backslash escapes (default) SELECT foo, bar FROM db WHERE foo='baz' [root@Betty Shell]# [root@Betty Shell]# echo "$sql" SELECT foo, bar FROM db WHERE foo='baz' [root@Betty Shell]# [root@Betty Shell]# echo -e "$sql" -e enable interpretation of backslash escapes SELECT foo, bar FROM db WHERE foo='baz' [root@Betty Shell]# [root@Betty Shell]# echo -E "$sql" -E disable interpretation of backslash escapes (default) SELECT foo, bar FROM db WHERE foo='baz' [root@Betty Shell]#執行後,$sql 變量中將會包含帶換行符的字串,你能夠經過 echo -e "$sql" 命令進行查看。
[root@Betty Shell]# cat <<EOF > print.sh > #!/bin/bash > echo \$PWD > echo $PWD > EOFThe print.sh file now contains:
[root@Betty Shell]# cat print.sh #!/bin/bash echo $PWD -- 未被命令替換 echo /root/workspace/CODE_TEST/Shell -- 被命令替換例子三:將多行字符串傳遞給一個 command/pipe
[root@Betty Shell]# cat <<EOF | grep 'b' | tee b.txt | grep 'r' > foo > bar > baz > EOF bar上述命令只將 bar 打印到標準輸出,但會建立 b.txt 文件,其中包含了 bar 和 baz 兩行字符串。
[root@Betty Shell]# cat >> test <<HERE > Hello world HERE <--- Not the end of string > HERE <-- Leading space, so not end of string > HERE <-- Now we have the end of the string [root@Betty Shell]# cat test Hello world HERE HERE
1. Linux man 手冊
2. bash read 背後的故事二:read -r
3. 關於 cat > file 和 cat > file <<EOF
4. Here document
5. how does ` cat << EOF` work in bash?
linux