testconstructs.html
来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 1,203 行 · 第 1/2 页
HTML
1,203 行
>[</B> , 是调用<BCLASS="COMMAND">test</B>命令的标识. 而关闭条件判断用的的右中括号, <BCLASS="COMMAND">]</B>, 在if/test结构中并不是严格必需的, 但是在Bash的新版本中必须要求使用. </P><DIVCLASS="NOTE"><P></P><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/note.gif"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P><BCLASS="COMMAND">test</B>命令在Bash中是<AHREF="internal.html#BUILTINREF">内建</A>命令, 用来测试文件类型, 或者用来比较字符串. 因此, 在Bash脚本中, <BCLASS="COMMAND">test</B>命令并<EM>不会</EM>调用外部的<TTCLASS="FILENAME">/usr/bin/test</TT>中的test命令, 这是<EM>sh-utils</EM>工具包中的一部分. 同样的, <SPANCLASS="TOKEN">[</SPAN>也并不会调用<TTCLASS="FILENAME">/usr/bin/[</TT>, 这是<TTCLASS="FILENAME">/usr/bin/test</TT>的符号链接.</P><P> <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">type test</KBD><SAMPCLASS="COMPUTEROUTPUT">test is a shell builtin</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">type '['</KBD><SAMPCLASS="COMPUTEROUTPUT">[ is a shell builtin</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">type '[['</KBD><SAMPCLASS="COMPUTEROUTPUT">[[ is a shell keyword</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">type ']]'</KBD><SAMPCLASS="COMPUTEROUTPUT">]] is a shell keyword</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">type ']'</KBD><SAMPCLASS="COMPUTEROUTPUT">bash: type: ]: not found</SAMP> </PRE></FONT></TD></TR></TABLE> </P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="EX11"></A><P><B>例子 7-2. <SPANCLASS="TOKEN">test</SPAN>, <TTCLASS="FILENAME">/usr/bin/test</TT>, <SPANCLASS="TOKEN">[ ]</SPAN>, 和<TTCLASS="FILENAME">/usr/bin/[</TT>都是等价命令</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 echo 4 5 if test -z "$1" 6 then 7 echo "No command-line arguments." 8 else 9 echo "First command-line argument is $1." 10 fi 11 12 echo 13 14 if /usr/bin/test -z "$1" # 与内建的"test"命令结果相同. 15 then 16 echo "No command-line arguments." 17 else 18 echo "First command-line argument is $1." 19 fi 20 21 echo 22 23 if [ -z "$1" ] # 与上边的代码块作用相同. 24 # if [ -z "$1" 应该能够运行, 但是... 25 #+ Bash报错, 提示缺少关闭条件测试的右中括号. 26 then 27 echo "No command-line arguments." 28 else 29 echo "First command-line argument is $1." 30 fi 31 32 echo 33 34 35 if /usr/bin/[ -z "$1" ] # 再来一个, 与上边的代码块作用相同. 36 # if /usr/bin/[ -z "$1" # 能够工作, 但是还是给出一个错误消息. 37 # # 注意: 38 # 在版本3.x的Bash中, 这个bug已经被修正了. 39 then 40 echo "No command-line arguments." 41 else 42 echo "First command-line argument is $1." 43 fi 44 45 echo 46 47 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P><ANAME="DBLBRACKETS"></A><SPANCLASS="TOKEN">[[ ]]</SPAN>结构比<SPANCLASS="TOKEN">[ ]结构更加通用</SPAN>. 这是一个<EM>扩展的test命令</EM>, 是从<EM>ksh88</EM>中引进的.</P><DIVCLASS="NOTE"><P></P><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/note.gif"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>在<SPANCLASS="TOKEN">[[</SPAN>和<SPANCLASS="TOKEN">]]</SPAN>之间所有的字符都不会发生文件名扩展或者单词分割, 但是会发生参数扩展和命令替换. </P></TD></TR></TABLE></DIV><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 file=/etc/passwd 2 3 if [[ -e $file ]] 4 then 5 echo "Password file exists." 6 fi</PRE></FONT></TD></TR></TABLE> </P><DIVCLASS="TIP"><P></P><TABLECLASS="TIP"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/tip.gif"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>使用<BCLASS="COMMAND">[[ ... ]]</B>条件判断结构, 而不是<BCLASS="COMMAND">[ ... ]</B>, 能够防止脚本中的许多逻辑错误. 比如, <SPANCLASS="TOKEN">&&</SPAN>, <SPANCLASS="TOKEN">||</SPAN>, <SPANCLASS="TOKEN"><</SPAN>, 和<SPANCLASS="TOKEN">></SPAN> 操作符能够正常存在于<SPANCLASS="TOKEN">[[ ]]</SPAN>条件判断结构中, 但是如果出现在<SPANCLASS="TOKEN">[ ]</SPAN>结构中的话, 会报错.</P></TD></TR></TABLE></DIV><DIVCLASS="NOTE"><P></P><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/note.gif"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>在<BCLASS="COMMAND">if</B>后面也不一定非得是<BCLASS="COMMAND">test</B>命令或者是用于条件判断的中括号结构( [ ] 或 [[ ]] ). <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 dir=/home/bozo 2 3 if cd "$dir" 2>/dev/null; then # "2>/dev/null" 会隐藏错误信息. 4 echo "Now in $dir." 5 else 6 echo "Can't change to $dir." 7 fi</PRE></FONT></TD></TR></TABLE> "if COMMAND"结构将会返回COMMAND的退出状态码.</P><P>与此相似, 在中括号中的条件判断也不一定非得要<BCLASS="COMMAND">if</B>不可, 也可以使用<AHREF="list-cons.html#LISTCONSREF">列表结构</A>. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 var1=20 2 var2=22 3 [ "$var1" -ne "$var2" ] && echo "$var1 is not equal to $var2" 4 5 home=/home/bozo 6 [ -d "$home" ] || echo "$home directory does not exist."</PRE></FONT></TD></TR></TABLE></P></TD></TR></TABLE></DIV><P><AHREF="dblparens.html">(( ))结构</A>扩展并计算一个算术表达式的值. 如果表达式的结果为0, 那么返回的<AHREF="exit-status.html#EXITSTATUSREF">退出状态码</A>为<SPANCLASS="RETURNVALUE">1</SPAN>, 或者是<SPANCLASS="QUOTE">"假"</SPAN>. 而一个非零值的表达式所返回的退出状态码将为<SPANCLASS="RETURNVALUE">0</SPAN>, 或者是<SPANCLASS="QUOTE">"true"</SPAN>. 这种情况和先前所讨论的<BCLASS="COMMAND">test</B>命令和<SPANCLASS="TOKEN">[ ]</SPAN>结构的行为正好相反. </P><DIVCLASS="EXAMPLE"><HR><ANAME="ARITHTESTS"></A><P><B>例子 7-3. 算术测试需要使用<SPANCLASS="TOKEN">(( ))</SPAN></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # 算术测试. 3 4 # (( ... ))结构可以用来计算并测试算术表达式的结果. 5 # 退出状态将会与[ ... ]结构完全相反! 6 7 (( 0 )) 8 echo "Exit status of \"(( 0 ))\" is $?." # 1 9 10 (( 1 )) 11 echo "Exit status of \"(( 1 ))\" is $?." # 0 12 13 (( 5 > 4 )) # 真 14 echo "Exit status of \"(( 5 > 4 ))\" is $?." # 0 15 16 (( 5 > 9 )) # 假 17 echo "Exit status of \"(( 5 > 9 ))\" is $?." # 1 18 19 (( 5 - 5 )) # 0 20 echo "Exit status of \"(( 5 - 5 ))\" is $?." # 1 21 22 (( 5 / 4 )) # 除法也可以. 23 echo "Exit status of \"(( 5 / 4 ))\" is $?." # 0 24 25 (( 1 / 2 )) # 除法的计算结果 < 1. 26 echo "Exit status of \"(( 1 / 2 ))\" is $?." # 截取之后的结果为 0. 27 # 1 28 29 (( 1 / 0 )) 2>/dev/null # 除数为0, 非法计算. 30 # ^^^^^^^^^^^ 31 echo "Exit status of \"(( 1 / 0 ))\" is $?." # 1 32 33 # "2>/dev/null"起了什么作用? 34 # 如果这句被删除会怎样? 35 # 尝试删除这句, 然后在运行这个脚本. 36 37 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="tests.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">首页</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="fto.html"ACCESSKEY="N">下一页</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">条件判断</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="tests.html"ACCESSKEY="U">上一级</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">文件测试操作符</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?