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