shell函数介绍和使用

1. shell中的函数

 1.1 函数优点

  函数的优点:代码模块化,调用方便,节省内存;代码量少,排错简单; 可以改变代码的执行顺序

 1.2 函数语法

  语法一(推荐使用):
  函数名 () {
    代码块
    return N
  }

  语法二:
  function 函数名 {
    代码块
    return N
  }

 1.3 函数应用

  shell中调用函数时,不用加小括号,直接写函数名就可以。

  实现一个10的阶乘函数。

    注意: 使用 let方式进行计算时,调用变量时可以不用写 $符;双小括号(()) 必须得写 $符。

    例子中 循环体的五种计算方式都可以, 推荐使用 let 方式来计算

#!/bin/bash
factorial() {
    result=1
    for((i=1; i<=10; i++))
    do
        #result=$(($result * $i))
     #let result=$result*$i
#let result=result*i
     #let result*=$i
     let result*=i
done echo "10的阶乘为$result" return 0 }
# 调用函数,不用加() factorial

 1.4 函数传参

  1. 位置传参

#!/bin/bash

factorial() {
    result=1
    for((i=1; i<=$1; i++))
    do
        result=$(($result * $i))
    done
    echo "$1的阶乘为$result"
    return 0
}

# 调用函数,不用加()
factorial $1
factorial $2
factorial $3

# 结果如下
3的阶乘为6
5的阶乘为120
10的阶乘为3628800

  2. 数组传参

  第一种:把数组的所有元素分散开传进函数,然后在函数内部用 $@ 或 $* 或 "$@"来接收所有参数,但是不能用 "$*"接收;是有区别的(具体区别见https://www.cnblogs.com/bk9527/p/12663949.html,预变量有详细说明)。

#!/bin/bash
arr=(1 2 3 4 5)

get_sum() {
  sum=0
  for i in $*;do
    let sum+=i
  done
  echo $sum
}

echo "get the array sum is `get_sum ${arr[@]}`"

结果如下:
get the array sum is 15

  第二种:给函数传参时 用   函数名 "${数组名[@]}"。当 "$*" 用双引号引起来时,会将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。

#!/bin/bash

arr_origin=(5 8 9)

get_sum() {
  arr=($1)    # 用()括起来, 和入参的长度保持一致
  echo "个数: ${#arr[@]}"
  result=0
  for i in ${arr[@]}; do
     let result+=i
  done
  echo $result
}

get_sum "${arr_origin[*]}"   # 一定要使用 "$*", 并用双引号引起来,即将数组的所有元素看做一份数据,传入函数中的arr就是数组所有的元素。
                 # 如果用 "$@", 那么传入函数中的arr变量就只有数组的第一个元素——5,就犯错了!!!

  3. 数组入参, 数组出参

  传入一个数组,并把处理后的数组传出。

    注意:在shell中,不管是在函数外部还是函数里面,如果不加local声明的话,那么这些个变量都是全局变量,即使在函数内部声明的变量,在函数外部也能调用。

       为了防止冲突,在函数内部使用的变量,最好用local声明,表示局部变量,仅函数内部使用。

#!/bin/bash
#传入一个数组,将处理后的数组传出

arr=(1 2 3)
out_arr_func() {
    local n      # 这里的local表示 变量n 和变量out_arr 都是局部变量, 在函数外部不能引用。
    local out_arr
    for i in $*; do
        out_arr[n++]=$(($i * 5))
    done
    echo ${out_arr[*]}
}

#result=`out_arr_func ${arr[*]}`
#echo "the result is $result"
#echo "in the function out_arr is ${out_arr[*]}"


#result=$(out_arr_func ${arr[*]})
#echo "the result is $result"
#echo "in the function out_arr is ${out_arr[*]}"


out_arr_func ${arr[*]}
echo "in the function out_arr is ${out_arr[*]}"

     

 1.5 shell函数返回值

  1. return 返回值 -- 即函数的执行状态

    在 C++、Java、C#、Python 等大部分编程语言中,返回值是指函数被调用之后,执行函数体中的代码所得到的结果,这个结果就通过 return 关键字返回;

    但是 Shell 中的 return 返回值表示的是函数的退出状态:默认的返回值为 0 表示函数执行成功了,返回值为非 0 表示函数执行失败(出错)了。if、while、for 等语句都是根据函数的退出状态来判断条件是否成立。函数执行失败时,我们可以自定义return返回值,这样就可以根据返回值(退出状态)来判断具体出现了什么错误,比如一个打开文件的函数,我们可以指定 1 表示文件不存在,2 表示文件没有读取权限,3 表示文件类型不对。

    $? 是一个特殊变量,用来获取上一个命令的退出状态,或者上一个函数的返回值,我们可以根据 $? 来获取上一个函数的执行状态(执行成功或执行失败的类型)

#!/bin/bash

test() {
  echo "arg1 = $1"
  if [ $1 == "1" ]; then
    return 111
  else
    return 100
  fi
}

test 1
echo "该函数的执行状态值为$?"


执行结果如下:
arg1 = 1
该函数的执行状态值为111

  2. echo 返回值 -- 获取函数处理后的结果

    如何得到函数的处理结果呢?比如,定义了一个函数,计算从 m 加到 n 的和,最终得到的结果该如何返回呢?  

    这个问题有两种解决方案:

      一种是借助全局变量,将得到的结果赋值给全局变量,直接使用全局变量

#!/bin/bash

result=1        # 全局变量
factorial() {
    result=1
    for((i=1; i<=10; i++))
    do
        let result*=i
    done
    return 198
}

factorial
echo "the last result is $result"

结果如下:
the last result is 3628800

      一种是在函数内部使用 echo、printf 命令将结果输出,在函数外部使用$()或者``捕获结果。

#!/bin/bash

factorial() {
    result=1
    for((i=1; i<=10; i++))
    do
        let result*=i
    done
    echo "10的阶乘为$result"
    return 198
}

out_result=`factorial`
echo "the last result is $out_result"
echo "the last result also is $(factorial)"

结果如下:
the last result is 10的阶乘为3628800
the last result also is 10的阶乘为3628800

   `` 或 $() 捕获了echo的输出结果,并将结果赋值给变量out_result 或 直接输出结果。

原文地址:https://www.cnblogs.com/bk9527/p/12832432.html