⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gotchas.html

📁 一本完整的描述Unix Shell 编程的工具书的所有范例
💻 HTML
📖 第 1 页 / 共 2 页
字号:
   6&nbsp;chmod 755 $0   # Change back to execute permission.   7&nbsp;               # The 'unix2dos' command removes execute permission.   8&nbsp;   9&nbsp;./$0           # Script tries to run itself again.  10&nbsp;               # But it won't work as a DOS file.  11&nbsp;  12&nbsp;echo "There"  13&nbsp;  14&nbsp;exit 0</PRE></TD></TR></TABLE>      </P><P>A shell script headed by <TTCLASS="USERINPUT"><B>#!/bin/sh</B></TT>	will not run in full Bash-compatibility mode. Some Bash-specific	functions might be disabled. Scripts that need complete	access to all the Bash-specific extensions should start with	<TTCLASS="USERINPUT"><B>#!/bin/bash</B></TT>.</P><P><AHREF="here-docs.html#INDENTEDLS">Putting whitespace in front of	the terminating limit string</A> of a <AHREF="here-docs.html#HEREDOCREF">here document</A> will cause unexpected	behavior in a script.</P><P><ANAME="PARCHILDPROBREF"></A></P><P>A script may not <BCLASS="COMMAND">export</B> variables back	to its <AHREF="internal.html#FORKREF">parent process</A>, the shell,	or to the environment. Just as we learned in biology, a child	process can inherit from a parent, but not vice versa.	  <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;WHATEVER=/home/bozo   2&nbsp;export WHATEVER   3&nbsp;exit 0</PRE></TD></TR></TABLE>          <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash$ </TT><BCLASS="COMMAND">echo $WHATEVER</B> <TTCLASS="COMPUTEROUTPUT"></TT> <TTCLASS="PROMPT">bash$ </TT></PRE></TD></TR></TABLE>        Sure enough, back at the command prompt, $WHATEVER remains unset. 		  	  </P><P>Setting and manipulating variables in a <AHREF="subshells.html#SUBSHELLSREF">subshell</A>, then attempting        to use those same variables outside the scope of the subshell will	result an unpleasant surprise.</P><DIVCLASS="EXAMPLE"><HR><ANAME="SUBPIT"></A><P><B>Example 31-2. Subshell Pitfalls</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# Pitfalls of variables in a subshell.   3&nbsp;   4&nbsp;outer_variable=outer   5&nbsp;echo   6&nbsp;echo "outer_variable = $outer_variable"   7&nbsp;echo   8&nbsp;   9&nbsp;(  10&nbsp;# Begin subshell  11&nbsp;  12&nbsp;echo "outer_variable inside subshell = $outer_variable"  13&nbsp;inner_variable=inner  # Set  14&nbsp;echo "inner_variable inside subshell = $inner_variable"  15&nbsp;outer_variable=inner  # Will value change globally?  16&nbsp;echo "outer_variable inside subshell = $outer_variable"  17&nbsp;  18&nbsp;# Will 'exporting' make a difference?  19&nbsp;#    export inner_variable  20&nbsp;#    export outer_variable  21&nbsp;# Try it and see.  22&nbsp;  23&nbsp;# End subshell  24&nbsp;)  25&nbsp;  26&nbsp;echo  27&nbsp;echo "inner_variable outside subshell = $inner_variable"  # Unset.  28&nbsp;echo "outer_variable outside subshell = $outer_variable"  # Unchanged.  29&nbsp;echo  30&nbsp;  31&nbsp;exit 0  32&nbsp;  33&nbsp;# What happens if you uncomment lines 19 and 20?  34&nbsp;# Does it make a difference?</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="BADREAD0"></A></P><P><AHREF="special-chars.html#PIPEREF">Piping</A>	<BCLASS="COMMAND">echo</B> output to a <AHREF="internal.html#READREF">read</A> may produce unexpected	results.  In this scenario, the <BCLASS="COMMAND">read</B>	acts as if it were running in a subshell. Instead, use	the <AHREF="internal.html#SETREF">set</A> command (as in <AHREF="internal.html#SETPOS">Example 11-16</A>).</P><DIVCLASS="EXAMPLE"><HR><ANAME="BADREAD"></A><P><B>Example 31-3. Piping the output of <BCLASS="COMMAND">echo</B> to a <BCLASS="COMMAND">read</B></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;#  badread.sh:   3&nbsp;#  Attempting to use 'echo and 'read'   4&nbsp;#+ to assign variables non-interactively.   5&nbsp;   6&nbsp;a=aaa   7&nbsp;b=bbb   8&nbsp;c=ccc   9&nbsp;  10&nbsp;echo "one two three" | read a b c  11&nbsp;# Try to reassign a, b, and c.  12&nbsp;  13&nbsp;echo  14&nbsp;echo "a = $a"  # a = aaa  15&nbsp;echo "b = $b"  # b = bbb  16&nbsp;echo "c = $c"  # c = ccc  17&nbsp;# Reassignment failed.  18&nbsp;  19&nbsp;# ------------------------------  20&nbsp;  21&nbsp;# Try the following alternative.  22&nbsp;  23&nbsp;var=`echo "one two three"`  24&nbsp;set -- $var  25&nbsp;a=$1; b=$2; c=$3  26&nbsp;  27&nbsp;echo "-------"  28&nbsp;echo "a = $a"  # a = one  29&nbsp;echo "b = $b"  # b = two  30&nbsp;echo "c = $c"  # c = three   31&nbsp;# Reassignment succeeded.  32&nbsp;  33&nbsp;# ------------------------------  34&nbsp;  35&nbsp;#  Note also that an echo to a 'read' works within a subshell.  36&nbsp;#  However, the value of the variable changes *only* within the subshell.  37&nbsp;  38&nbsp;a=aaa          # Starting all over again.  39&nbsp;b=bbb  40&nbsp;c=ccc  41&nbsp;  42&nbsp;echo; echo  43&nbsp;echo "one two three" | ( read a b c;  44&nbsp;echo "Inside subshell: "; echo "a = $a"; echo "b = $b"; echo "c = $c" )  45&nbsp;# a = one  46&nbsp;# b = two  47&nbsp;# c = three  48&nbsp;echo "-----------------"  49&nbsp;echo "Outside subshell: "  50&nbsp;echo "a = $a"  # a = aaa  51&nbsp;echo "b = $b"  # b = bbb  52&nbsp;echo "c = $c"  # c = ccc  53&nbsp;echo  54&nbsp;  55&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><P>In fact, as Anthony Richardson points out, piping to        <ICLASS="EMPHASIS">any</I> loop can cause a similar problem.</P><P>	<TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;# Loop piping troubles.   2&nbsp;#  This example by Anthony Richardson,   3&nbsp;#+ with addendum by Wilbert Berendsen.   4&nbsp;   5&nbsp;   6&nbsp;foundone=false   7&nbsp;find $HOME -type f -atime +30 -size 100k |   8&nbsp;while true   9&nbsp;do  10&nbsp;   read f  11&nbsp;   echo "$f is over 100KB and has not been accessed in over 30 days"  12&nbsp;   echo "Consider moving the file to archives."  13&nbsp;   foundone=true  14&nbsp;   # ------------------------------------  15&nbsp;   echo "Subshell level = $BASH_SUBSHELL"  16&nbsp;   # Subshell level = 1  17&nbsp;   # Yes, we're inside a subshell.  18&nbsp;   # ------------------------------------  19&nbsp;done  20&nbsp;     21&nbsp;#  foundone will always be false here since it is  22&nbsp;#+ set to true inside a subshell  23&nbsp;if [ $foundone = false ]  24&nbsp;then  25&nbsp;   echo "No files need archiving."  26&nbsp;fi  27&nbsp;  28&nbsp;# =====================Now, here is the correct way:=================  29&nbsp;  30&nbsp;foundone=false  31&nbsp;for f in $(find $HOME -type f -atime +30 -size 100k)  # No pipe here.  32&nbsp;do  33&nbsp;   echo "$f is over 100KB and has not been accessed in over 30 days"  34&nbsp;   echo "Consider moving the file to archives."  35&nbsp;   foundone=true  36&nbsp;done  37&nbsp;     38&nbsp;if [ $foundone = false ]  39&nbsp;then  40&nbsp;   echo "No files need archiving."  41&nbsp;fi  42&nbsp;  43&nbsp;# ==================And here is another alternative==================  44&nbsp;  45&nbsp;#  Places the part of the script that reads the variables  46&nbsp;#+ within a code block, so they share the same subshell.  47&nbsp;#  Thank you, W.B.  48&nbsp;  49&nbsp;find $HOME -type f -atime +30 -size 100k | {  50&nbsp;     foundone=false  51&nbsp;     while read f  52&nbsp;     do  53&nbsp;       echo "$f is over 100KB and has not been accessed in over 30 days"  54&nbsp;       echo "Consider moving the file to archives."  55&nbsp;       foundone=true  56&nbsp;     done  57&nbsp;  58&nbsp;     if ! $foundone  59&nbsp;     then  60&nbsp;       echo "No files need archiving."  61&nbsp;     fi  62&nbsp;}</PRE></TD></TR></TABLE>      </P><P>        A related problem occurs when trying to write the	<TTCLASS="FILENAME">stdout</TT> of a <BCLASS="COMMAND">tail -f</B>	piped to <AHREF="textproc.html#GREPREF">grep</A>.	  <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;tail -f /var/log/messages | grep "$ERROR_MSG" &#62;&#62; error.log   2&nbsp;# The "error.log" file will not have anything written to it.</PRE></TD></TR></TABLE>      </P><P>--</P><P>Using <SPANCLASS="QUOTE">"suid"</SPAN> commands within scripts is risky,	as it may compromise system security.	  <ANAME="AEN15214"HREF="#FTN.AEN15214">[1]</A>      </P><P>Using shell scripts for CGI programming may be problematic. Shell        script variables are not <SPANCLASS="QUOTE">"typesafe"</SPAN>, and this can cause	undesirable behavior as far as CGI is concerned. Moreover, it is	difficult to <SPANCLASS="QUOTE">"cracker-proof"</SPAN> shell scripts.</P><P>Bash does not handle the <AHREF="internal.html#DOUBLESLASHREF">double slash        (<SPANCLASS="TOKEN">//</SPAN>) string</A> correctly.</P><P>Bash scripts written for Linux or BSD systems may need	fixups to run on a commercial UNIX (or Apple OSX) machine. Such	scripts often employ GNU commands and filters which have greater	functionality than their generic UNIX counterparts. This is	particularly true of such text processing utilites as <AHREF="textproc.html#TRREF">tr</A>.</P><TABLEBORDER="0"WIDTH="100%"CELLSPACING="0"CELLPADDING="0"CLASS="EPIGRAPH"><TR><TDWIDTH="45%">&nbsp;</TD><TDWIDTH="45%"ALIGN="LEFT"VALIGN="TOP"><I><P><I>Danger is near thee --</I></P><P><I>Beware, beware, beware, beware.</I></P><P><I>Many brave hearts are asleep in the deep.</I></P><P><I>So beware --</I></P><P><I>Beware.</I></P></I></TD></TR><TR><TDWIDTH="45%">&nbsp;</TD><TDWIDTH="45%"ALIGN="RIGHT"VALIGN="TOP"><I><SPANCLASS="ATTRIBUTION">A.J. Lamb and H.W. Petrie</SPAN></I></TD></TR></TABLE></DIV><H3CLASS="FOOTNOTES">Notes</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN15214"HREF="gotchas.html#AEN15214">[1]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>Setting the <ICLASS="EMPHASIS">suid</I> permission on	    the script itself has no effect.</P></TD></TR></TABLE><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLEWIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="options.html">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="scrstyle.html">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Options</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part4.html">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Scripting With Style</TD></TR></TABLE></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -