functions.html
来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 437 行
HTML
437 行
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><HTML><HEAD><TITLE>函数</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINKREL="HOME"TITLE="高级Bash脚本编程指南"HREF="index.html"><LINKREL="UP"TITLE="高级主题"HREF="part4.html"><LINKREL="PREVIOUS"TITLE="进程替换"HREF="process-sub.html"><LINKREL="NEXT"TITLE="复杂函数和函数复杂性"HREF="complexfunct.html"></HEAD><BODYCLASS="CHAPTER"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">高级Bash脚本编程指南: 一本深入学习shell脚本艺术的书籍</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="process-sub.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="complexfunct.html"ACCESSKEY="N">下一页</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1><ANAME="FUNCTIONS"></A>23. 函数</H1><DIVCLASS="TOC"><DL><DT><B>目录</B></DT><DT>23.1. <AHREF="complexfunct.html">复杂函数和函数复杂性</A></DT><DT>23.2. <AHREF="localvar.html">局部变量</A></DT><DT>23.3. <AHREF="recurnolocvar.html">不使用局部变量的递归</A></DT></DL></DIV><P><ANAME="FUNCTIONREF"></A></P><P>与<SPANCLASS="QUOTE">"真正的"</SPAN>编程语言一样, Bash也有函数, 虽然在某些实现方面稍有限制. 一个函数就是一个子程序, 用于实现一系列操作的<AHREF="special-chars.html#CODEBLOCKREF">代码块</A>, 它是完成特定任务的<SPANCLASS="QUOTE">"黑盒子"</SPAN>. 当存在重复代码的时候, 或者当一个任务只需要轻微修改就被重复使用的时候, 你就需要考虑使用函数了. </P><P><P><BCLASS="COMMAND">function</B> <TTCLASS="REPLACEABLE"><I>function_name</I></TT> { <BR> <TTCLASS="REPLACEABLE"><I>command</I></TT>... <BR> } <BR></P> 或 <P> <TTCLASS="REPLACEABLE"><I>function_name</I></TT> () { <BR> <TTCLASS="REPLACEABLE"><I>command</I></TT>... <BR> } <BR></P> </P><P>C程序员肯定会更加喜欢第二中格式的写法(并且这种写法可移植性更好). </P><P>在C中, 函数的左大括号也可以写在下一行中. </P><P><P> <TTCLASS="REPLACEABLE"><I>function_name</I></TT> () <BR> { <BR> <TTCLASS="REPLACEABLE"><I>command</I></TT>... <BR> } <BR></P> </P><P>只需要简单的调用函数名, 函数就会被调用或<ICLASS="FIRSTTERM">触发</I>. </P><DIVCLASS="EXAMPLE"><HR><ANAME="EX59"></A><P><B>例子 23-1. 简单函数</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 JUST_A_SECOND=1 4 5 funky () 6 { # 这是一个最简单的函数. 7 echo "This is a funky function." 8 echo "Now exiting funky function." 9 } # 函数必须在调用前声明. 10 11 12 fun () 13 { # 一个稍微复杂一些的函数. 14 i=0 15 REPEATS=30 16 17 echo 18 echo "And now the fun really begins." 19 echo 20 21 sleep $JUST_A_SECOND # 嘿, 暂停一秒! 22 while [ $i -lt $REPEATS ] 23 do 24 echo "----------FUNCTIONS---------->" 25 echo "<------------ARE-------------" 26 echo "<------------FUN------------>" 27 echo 28 let "i+=1" 29 done 30 } 31 32 # 现在, 调用这两个函数. 33 34 funky 35 fun 36 37 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P>函数定义必须在第一次调用函数之前完成. 没有像C中函数<SPANCLASS="QUOTE">"声明"</SPAN>的方法. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 f1 2 # 因为函数"f1"还没有被定义, 这会产生一个错误. 3 4 declare -f f1 # 这样也没用. 5 f1 # 仍然会引起错误. 6 7 # 然而... 8 9 10 f1 () 11 { 12 echo "Calling function \"f2\" from within function \"f1\"." 13 f2 14 } 15 16 f2 () 17 { 18 echo "Function \"f2\"." 19 } 20 21 f1 # 虽然在f2在定义前被引用过, 22 #+ 实际上f2到这儿才被调用. 23 # 所以这么做是正常的. 24 25 # 感谢, S.C.</PRE></FONT></TD></TR></TABLE> </P><P>甚至可以在一个函数内嵌套另一个函数, 虽然这么做并没有多大用处. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 f1 () 2 { 3 4 f2 () # nested 5 { 6 echo "Function \"f2\", inside \"f1\"." 7 } 8 9 } 10 11 f2 # 产生一个错误. 12 # 即使你先写出"declare -f f2"也没用. 13 14 echo 15 16 f1 # 什么事都没干, 因为调用"f1"并不会自动调用"f2". 17 f2 # 现在, 可以正确的调用"f2"了, 18 #+ 因为之前调用"f1"使"f2"在脚本中变得可见了. 19 20 # 感谢, S.C.</PRE></FONT></TD></TR></TABLE> </P><P>函数声明可以出现在看上去不可能出现的地方, 比如说本应出现命令的地方, 也可以出现函数声明. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 ls -l | foo() { echo "foo"; } # 可以这么做, 但没什么用. 2 3 4 5 if [ "$USER" = bozo ] 6 then 7 bozo_greet () # 在if/then结构中定义了函数. 8 { 9 echo "Hello, Bozo." 10 } 11 fi 12 13 bozo_greet # 只能由Bozo运行, 其他用户使用的话, 会引起错误. 14 15 16 17 # 在某些上下文中, 这样做可能会有用. 18 NO_EXIT=1 # 将会打开下面的函数定义. 19 20 [[ $NO_EXIT -eq 1 ]] && exit() { true; } # 在"与列表"中定义函数. 21 # 如果$NO_EXIT为1, 那就声明"exit ()". 22 # 把"exit"化名为"true", 将会禁用内建的"exit"命令. 23 24 exit # 这里调用的是"exit ()"函数, 而不是"exit"内建命令. 25 26 # 感谢, S.C.</PRE></FONT></TD></TR></TABLE> </P></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="process-sub.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="complexfunct.html"ACCESSKEY="N">下一页</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">进程替换</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part4.html"ACCESSKEY="U">上一级</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">复杂函数和函数复杂性</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?