📄 internal.html
字号:
><ANAME="READTIMED"></A></P><P>The <TTCLASS="OPTION">-t</TT> option to <BCLASS="COMMAND">read</B> permits timed input (see <AHREF="variables2.html#TOUT">Example 9-4</A>).</P><P><ANAME="READREDIR0"></A></P><P>The <BCLASS="COMMAND">read</B> command may also <SPANCLASS="QUOTE">"read"</SPAN> its variable value from a file <AHREF="io-redirection.html#IOREDIRREF">redirected</A> to <TTCLASS="FILENAME">stdin</TT>. If the file contains more than one line, only the first line is assigned to the variable. If <BCLASS="COMMAND">read</B> has more than one parameter, then each of these variables gets assigned a successive <AHREF="special-chars.html#WHITESPACEREF">whitespace-delineated</A> string. Caution!</P><DIVCLASS="EXAMPLE"><HR><ANAME="READREDIR"></A><P><B>Example 14-7. Using <ICLASS="FIRSTTERM">read</I> with <AHREF="io-redirection.html#IOREDIRREF">file redirection</A></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 read var1 <data-file 4 echo "var1 = $var1" 5 # var1 set to the entire first line of the input file "data-file" 6 7 read var2 var3 <data-file 8 echo "var2 = $var2 var3 = $var3" 9 # Note non-intuitive behavior of "read" here. 10 # 1) Rewinds back to the beginning of input file. 11 # 2) Each variable is now set to a corresponding string, 12 # separated by whitespace, rather than to an entire line of text. 13 # 3) The final variable gets the remainder of the line. 14 # 4) If there are more variables to be set than whitespace-terminated strings 15 # on the first line of the file, then the excess variables remain empty. 16 17 echo "------------------------------------------------" 18 19 # How to resolve the above problem with a loop: 20 while read line 21 do 22 echo "$line" 23 done <data-file 24 # Thanks, Heiner Steven for pointing this out. 25 26 echo "------------------------------------------------" 27 28 # Use $IFS (Internal Field Separator variable) to split a line of input to 29 # "read", if you do not want the default to be whitespace. 30 31 echo "List of all users:" 32 OIFS=$IFS; IFS=: # /etc/passwd uses ":" for field separator. 33 while read name passwd uid gid fullname ignore 34 do 35 echo "$name ($fullname)" 36 done </etc/passwd # I/O redirection. 37 IFS=$OIFS # Restore original $IFS. 38 # This code snippet also by Heiner Steven. 39 40 41 42 # Setting the $IFS variable within the loop itself 43 #+ eliminates the need for storing the original $IFS 44 #+ in a temporary variable. 45 # Thanks, Dim Segebart, for pointing this out. 46 echo "------------------------------------------------" 47 echo "List of all users:" 48 49 while IFS=: read name passwd uid gid fullname ignore 50 do 51 echo "$name ($fullname)" 52 done </etc/passwd # I/O redirection. 53 54 echo 55 echo "\$IFS still $IFS" 56 57 exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P><AHREF="special-chars.html#PIPEREF">Piping</A> output to a <ICLASS="FIRSTTERM">read</I>, using <AHREF="internal.html#ECHOREF">echo</A> to set variables <AHREF="gotchas.html#BADREAD0">will fail</A>.</P><P><ANAME="READPIPEREF"></A>Yet, piping the output of <AHREF="external.html#CATREF">cat</A> <SPANCLASS="emphasis"><ICLASS="EMPHASIS">seems</I></SPAN> to work.</P><P><ANAME="WHILEREADREF"></A></P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 cat file1 file2 | 2 while read line 3 do 4 echo $line 5 done</PRE></TD></TR></TABLE></P><P>However, as Bj鰊 Eriksson shows:</P><DIVCLASS="EXAMPLE"><HR><ANAME="READPIPE"></A><P><B>Example 14-8. Problems reading from a pipe</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/sh 2 # readpipe.sh 3 # This example contributed by Bjon Eriksson. 4 5 last="(null)" 6 cat $0 | 7 while read line 8 do 9 echo "{$line}" 10 last=$line 11 done 12 printf "\nAll done, last:$last\n" 13 14 exit 0 # End of code. 15 # (Partial) output of script follows. 16 # The 'echo' supplies extra brackets. 17 18 ############################################# 19 20 ./readpipe.sh 21 22 {#!/bin/sh} 23 {last="(null)"} 24 {cat $0 |} 25 {while read line} 26 {do} 27 {echo "{$line}"} 28 {last=$line} 29 {done} 30 {printf "nAll done, last:$lastn"} 31 32 33 All done, last:(null) 34 35 The variable (last) is set within the subshell but unset outside.</PRE></TD></TR></TABLE><HR></DIV><P>The <ICLASS="FIRSTTERM">gendiff</I> script, usually found in <TTCLASS="FILENAME">/usr/bin</TT> on many Linux distros, pipes the output of <AHREF="moreadv.html#FINDREF">find</A> to a <ICLASS="FIRSTTERM">while read</I> construct. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 find $1 \( -name "*$2" -o -name ".*$2" \) -print | 2 while read f; do 3 . . .</PRE></TD></TR></TABLE> </P></TD></TR></TABLE></DIV><DIVCLASS="TIP"><TABLECLASS="TIP"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/tip.png"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>It is possible to <ICLASS="FIRSTTERM">paste</I> text into the input field of a <ICLASS="FIRSTTERM">read</I>. See <AHREF="contributed-scripts.html#PADSW">Example A-39</A>.</P></TD></TR></TABLE></DIV></DD></DL></DIV><DIVCLASS="VARIABLELIST"><P><B><ANAME="INTFILESYSTEM1"></A>Filesystem</B></P><DL><DT><ANAME="CDREF"></A><BCLASS="COMMAND">cd</B></DT><DD><P>The familiar <BCLASS="COMMAND">cd</B> change directory command finds use in scripts where execution of a command requires being in a specified directory.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)</PRE></TD></TR></TABLE> [from the <AHREF="special-chars.html#COXEX">previously cited</A> example by Alan Cox]</P><P>The <TTCLASS="OPTION">-P</TT> (physical) option to <BCLASS="COMMAND">cd</B> causes it to ignore symbolic links.</P><P><BCLASS="COMMAND">cd -</B> changes to <AHREF="variables2.html#OLDPWD">$OLDPWD</A>, the previous working directory.</P><P><ANAME="DOUBLESLASHREF"></A></P><DIVCLASS="CAUTION"><TABLECLASS="CAUTION"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/caution.png"HSPACE="5"ALT="Caution"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>The <BCLASS="COMMAND">cd</B> command does not function as expected when presented with two forward slashes. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>cd //</B></TT> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>pwd</B></TT> <TTCLASS="COMPUTEROUTPUT">//</TT> </PRE></TD></TR></TABLE> The output should, of course, be <TTCLASS="COMPUTEROUTPUT">/</TT>. This is a problem both from the command line and in a script.</P></TD></TR></TABLE></DIV></DD><DT><ANAME="PWD2REF"></A><BCLASS="COMMAND">pwd</B></DT><DD><P>Print Working Directory. This gives the user's (or script's) current directory (see <AHREF="internal.html#EX37">Example 14-9</A>). The effect is identical to reading the value of the builtin variable <AHREF="variables2.html#PWDREF">$PWD</A>.</P></DD><DT><ANAME="DIRSD"></A><BCLASS="COMMAND">pushd</B>, <BCLASS="COMMAND">popd</B>, <BCLASS="COMMAND">dirs</B></DT><DD><P>This command set is a mechanism for bookmarking working directories, a means of moving back and forth through directories in an orderly manner. A pushdown stack is used to keep track of directory names. Options allow various manipulations of the directory stack.</P><P><ANAME="PUSHDREF"></A><TTCLASS="USERINPUT"><B>pushd dir-name</B></TT> pushes the path <TTCLASS="REPLACEABLE"><I>dir-name</I></TT> onto the directory stack and simultaneously changes the current working directory to <TTCLASS="REPLACEABLE"><I>dir-name</I></TT></P><P><ANAME="POPDREF"></A><BCLASS="COMMAND">popd</B> removes (pops) the top directory path name off the directory stack and simultaneously changes the current working directory to that directory popped from the stack.</P><P><ANAME="DIRSREF"></A><BCLASS="COMMAND">dirs</B> lists the contents of the directory stack (compare this with the <AHREF="variables2.html#DIRSTACKREF">$DIRSTACK</A> variable). A successful <BCLASS="COMMAND">pushd</B> or <BCLASS="COMMAND">popd</B> will automatically invoke <BCLASS="COMMAND">dirs</B>.</P><P>Scripts that require various changes to the current working directory without hard-coding the directory name changes can make good use of these commands. Note that the implicit <TTCLASS="VARNAME">$DIRSTACK</TT> array variable, accessible from within a script, holds the contents of the directory stack. </P><DIVCLASS="EXAMPLE"><HR><ANAME="EX37"></A><P><B>Example 14-9. Changing the current working directory</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 dir1=/usr/local 4 dir2=/var/spool 5 6 pushd $dir1 7 # Will do an automatic 'dirs' (list directory stack to stdout). 8 echo "Now in directory `pwd`." # Uses back-quoted 'pwd'. 9 10 # Now, do some stuff in directory 'dir1'. 11 pushd $dir2 12 echo "Now in directory `pwd`." 13 14 # Now, do some stuff in directory 'dir2'. 15 echo "The top entry in the DIRSTACK array is $DIRSTACK." 16 popd 17 echo "Now back in directory `pwd`." 18 19 # Now, do some more stuff in directory 'dir1'. 20 popd 21 echo "Now back in original working directory `pwd`." 22 23 exit 0 24 25 # What happens if you don't 'popd' -- then exit the script? 26 # Which directory do you end up in? Why?</PRE></TD></TR></TABLE><HR></DIV></DD></DL></DIV><DIVCLASS="VARIABLELIST"><P><B><ANAME="INTVAR1"></A>Variables</B></P><DL><DT><ANAME="LETREF"></A><BCLASS="COMMAND">let</B></DT><DD><P>The <BCLASS="COMMAND">let</B> command carries out arithmetic operations on variables. In many cases, it functions as a less complex version of <AHREF="moreadv.html#EXPRREF">expr</A>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX46"></A><P><B>Example 14-10. Letting <ICLASS="FIRSTTERM">let</I> do arithmetic.</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 echo 4 5 let a=11 # Same as 'a=11' 6 let a=a+5 # Equivalent to let "a = a + 5"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -