我以前的“的文章在shell脚本理解和写作功能 ”有可能给你如何在shell脚本编写功能的基本思路。 现在是时候更深入地了解功能特性,如局部变量的使用和递归。
Shell脚本的功能复杂性
局部变量
什么使变量局部? 它取决于声明变量的特定块。 声明为局部变量将会从代码块地方出现,即它的范围是局部的访问。 为了解释这件事,让我们来看下面的一个例子。
#!/bin/bash func( ) { local i=10 j=20 echo "i from func = $i" echo "j from func = $j" } echo "i outside func = $i" echo "j outside func = $j" func echo "i outside func = $i" echo "j outside func = $j" exit 0
在执行上述脚本时,输出将是。
i outside func = j outside func = i from func = 10 j from func = 20 i outside func = j outside func = 20
这是因为,当第一2回波语句被执行的函数func尚未调用。 调用函数func一样2 echo语句后产生不同的结果。 现在变量j,被宣布里面FUNC键 ,不是本地的,可事后访问。
因此,对于j值为20。 怎么样局部变量i? 因为其范围是函数func内,值10不能从外部访问。 需要注意的是,通常内部FUNC声明的变量j是通过默认全局。
现在,您熟悉局部变量以及如何在函数块中使用它们。 让我们继续讨论函数中最有趣的部分,递归。
什么是递归?
函数调用自身通常被称为递归过程。 或者它可以被定义为通过使用相同算法的更简单版本来表达算法。 考虑查找数字的阶乘的例子。 我们知道,N! = 1×2×3×... X(N-1)XN。 因此,我们可以写一个递推关系:
n! = (n-1)! x n
所以它容易我们递归调用相同的函数,并使用每次调用的返回值乘以前一个结果,即
5! = 4! x 5 4! = 3! x 4 3! = 2! x 3 2! = 1! x 2 1! = 0! x 1
使用局部变量递归
在这里,我们尝试编写一个脚本,用于使用局部变量和递归查找数字的阶乘。
#!/bin/bash fact( ) { local num=$1 if [ $num -eq 0 ]; then ret=1 else temp=$((num-1)) fact $temp ret=$((num*$?)) fi return $ret } fact 5 echo "Factorial of 5 = $?" exit 0
num是用于存储关于每个呼叫每一个n-1的值的本地变量。 这里,基本条件检查数字是否等于零(因为0!= 1,并且没有为负数定义阶乘)。 在到达此基础条件则返回值1到它的调用者。 现在,NUM = 1和RET = 1×1。
在这一时刻它返回1到它的调用者。 现在NUM = 2和RET = 2×1等。 最后,当NUM = 5返回值是24和最后的结果是RET = 5×24。最后的结果120向下传递到初始主叫方声明并显示。
上面的脚本有一个问题。 正如我在上一篇文章中解释的,函数不能返回大整数。 所以它给用户找到了解决上述问题的方法。
问:我们不使用局部变量执行递归? 答案是肯定的。
没有局部变量的递归
请看下面的例子显示使用递归的Fibonacci序列 。 基本递归关系为:
fib(0) = 0 fib(1) = 1 else fib(n) = fib(n-1) + fib(n-2) Fibonacci series using recursion #!/bin/bash fib( ) { a=$1 if [ $a -lt 2 ]; then echo $a else ((--a)) b=$(fib $a) ((--a)) c=$(fib $a) echo $((b+c)) fi } for i in $(seq 0 15) do out=$(fib $i) echo $out done exit 0
在上述脚本中没有使用局部变量。 我希望你可以在执行过程中理解脚本的流程。
这里的值15表示要显示在Fibonacci系列的项数。 你注意到有关执行上面的脚本有什么特别的。 需要一段时间,不是吗? 递归在脚本比像C编程语言中的递归慢。
在本文中,我计划在shell脚本中完成函数部分。 随时更新youcl会对阵列和即将发表的文章更多...