zoukankan      html  css  js  c++  java
  • 《Linux命令行与shell脚本编程大全》第十七章 创建函数

    可以将shell脚本代码放进函数中封装起来,这样就能在脚本中的任何地方多次使用它了。

    17.1 基本的脚本函数

    函数:是一个脚本代码块,可以为其命名并在代码中任何位置重用。

    17.1.1 创建函数

    有两种格式:name 是函数名

    1)

    function name

    {

             commands

    }

    2)这种就比较接近c语言风格了

    name()

    {

             commands

    }

    17.1.2 使用函数

    跟其他shell命令一样,在行中指定函数名就好了。

    在函数定义前使用函数,会收到一条错误消息。

    函数名是唯一的,如果重定义了函数,新的会覆盖旧的,并且不会产生任何错误消息。

    例子:

      1 #!/bin/bash

      2

      3 function fun

      4 {

      5         echo "hahahaha, i am a function"

      6 }

      7

      8 count=1

      9 while [ $count -lt 5 ]

     10 do

     11         fun

     12         count=$[ $count + 1 ]

     13 done

     14

     15 fun2  # Error fun2 not define

     16 fun2() # 声明函数的另外一种方式

     17 {

     18         echo "I am Fun2, hahaha"

     19 }

     20 fun2

    17.2 返回值

    函数运行结束会返回一个退出状态码,有3种方法为函数生成退出状态码。

    17.2.1 默认退出状态码

    在函数结束时用 $? 来确定函数的退出状态码。

    比如:

    fun

    echo “return code:$?”

    如果函数最后执行的语句失败了,这里就会返回非0,最后成功了(不管前面有没有失败)返回都是0.

    17.2.2 使用return命令

    bashshell使用return命令来退出函数并返回特定的退出状态码。return允许指定一个整数值来定义函数的退出状态码。

    注意:

    函数一结束就要立即取返回值

    退出状态码必须是0 – 255.(大于255会产生一个错误值)

    17.2.3 使用函数输出

    可以将函数输出(任何类型的函数输出)保存到shell变量中。

    语法:result=$(fun)  这个命令会将fun函数的输出赋给$result变量

    例子:

      1 #!/bin/bash

      2

      3 function fun

      4 {

      5         echo "hahahaha, i am a function"

      6         return 1

      7 }

      8

      9 fun

     10 echo "fun return $?"

     11

     12 function fun2

     13 {

     14         echo "This is Function fun2"

     15         read -p "Enter a value:" num

     16         echo $[ $num * 2 ]

     17 }

     18

     19 #fun2 # 如果加上这句就会调两次了。

     20 result=$(fun2)

     21 echo "fun2 return:$result"

     这样就可以返回浮点数和字符串了。

    17.3 在函数中使用变量

    介绍一些处理shell脚本函数内外变量的方法

    17.3.1 向函数传递参数

    就跟向脚本传递参数一样,可以用$# $0 $1 $2

    注意脚本主体的$1 $2 和传到函数里面的并不相同。

    例子:

      1 #!/bin/bash

      2 function add

      3 {

      4         if [ $# -eq 0 ] || [ $# -gt 2 ]

      5         then

      6                 echo -1

      7         elif [ $# -eq 1 ]

      8         then

      9                 echo $[ $1 + $1 ]

     10         else

     11                 echo $[ $1 + $2 ]

     12         fi

     13 }

     14

     15 #ret=$(add)

     16 #ret=$(add 34) # 这里说明的如何传入参数

     17 ret=$(add 23 18)

     18 if [ $ret -eq -1 ]

     19 then

     20         echo "Function add Error"

     21 else

     22         echo "The value = $ret"

     23 fi

     24

     25 if [ $# -eq 2 ] # 这个的脚本主体接收的参数个数

     26 then

     27         echo "The value is $(add $1 $2)" # 将脚本主体的参数传给里面的函数

     28 else

     29         echo "Input Error"

     30 fi

    17.3.2 在函数中处理变量

    变量的作用域比较麻烦。作用域是变量可见的区域。

    函数中定义的变量和普通变量的作用域不同,也就是说对脚本的其他部分来说它们是隐藏的

    函数使用两种类型的变量:全局变量和局部变量

    1.全局变量

    是指在shell脚本中任何地方都有效的变量。

    在脚本主体部分定义了全局变量,那么在函数内可以读取它的值。

    在函数内定义了全局变量,在脚本的主体部分也可以读取它的值。

    默认情况下,在脚本中定义的任何变量都是全局变量。函数外定义的变量可在函数内访问

    这样要特别注意变量的使用。很容易就改变了变量。

    2.局部变量

    可以在函数内部使用的任何变量都声明成局部变量。

    在变量声明前加上local关键字就好了

    local temp

    例子:

      1 #!/bin/bash

      2 function fun

      3 {

      4         #temp=$[ $value + 5 ] # 如果这个是全局变量下面的结果就会异常

      5         local temp=$[ $value + 5 ]

      6         ret=$[ $temp * 2 ]

      7 }

      8

      9 temp=4

     10 value=6

     11 fun

     12 echo "fun: ret = $ret"

     13 if [ $temp -gt $value ]

     14 then

     15         echo "temp is big"

     16 else

     17         echo "value is big"

     18 fi

    17.4 数组变量和函数

    第6章讨论了数组来在单个变量中保存多个值的高级用法

    17.4.1 向函数传数组参数

    复习一下数组的用法:

    定义方法1:初始化数组 array=(a b c)

    定义方法2:新建数组并添加原色  array[数组]=元素

    定义方法3:将命令输出作为数组元素 array=($(command))

    数组操作:

    1)获取所有元素:echo ${array[*]}

    2)获取第n个元素: echo ${array[n]}    n为数组下标

    3)添加元素:array[3]=d

    4)删除元素:unset array[n] n为数组下标

    1. 数组作为参数传递时不能用 $arrayName。

    应该这样: fun ${arrName[*]}

    还可以加上双引号。

    例子:

      1 #!/bin/bash

      2 function testit

      3 {

      4         echo "The param are:$@, Param count:$#"

      5         thisarray=$1

      6         echo "The received array is:${thisarray[*]}"

      7

      8         for param in "$@"

      9         do

     10                 echo "Param = $param"

     11         done

     12 }

     13

     14 myarray=(13 25 35 45 55 65)

     15 echo "The original array is: ${myarray[*]}"

     16 testit "${myarray[*]}"

     17 testit ${myarray[*]}

     有双引号时,函数接受的参数个数为1.

    17.4.2 从函数返回参数

    函数用echo语句来按正确顺序输出单个数组值,然后脚本再将它们重新放进一个新的数组变量中。

    例子:

      1 #!/bin/bash

      2 function fun

      3 {

      4         local origarray

      5         local newarray

      6         local count

      7         local i

      8         origarray=($(echo "$@"))

      9         newarray=($(echo "$@"))

     10         count=$[ $# - 1 ]

     11         for (( i = 0; i <= count; i++ ))

     12         {

     13                 newarray[$i]=$[ ${origarray[$i]} * 2 ]

     14         }

     15         echo ${newarray[*]}

     16 }

     17

     18 myarr=(1 2 3 4 5 6 7 8 9 10 11 12 13 14)

     19 echo "original arr is: ${myarr[*]}"

     20 arg1=$(echo ${myarr[*]}) # 这里的用命令输出定义数组

     21 ret=($(fun $arg1))

     22 echo "new arr is: ${ret[*]}"

    用arg1变量将数组值传给函数fun。函数将该数组重组到新的数组变量中。

    脚本用fun函数的输出来重新生成一个新的数组变量

    17.5 函数递归

    函数的返回值直接用echo传递了。

    例子:求阶乘(注意书上的例子p369 中间部分的 result ** 写错了)

      1 #!/bin/bash

      2 function fun1

      3 {

      4         if [ $1 -eq 1 ]

      5         then

      6                 echo 1

      7         else

      8                 local temp=$[ $1 - 1 ]

      9                 local ret=$(fun1 $temp)

     10                 echo $[ $ret * $1 ]

     11         fi

     12 }

     13

     14 read -p "Enter value:" value

     15 ret=$(fun1 $value)

     16 echo "ret = $ret"

    17.6 创建库

    允许创建函数库文件,然后在多个脚本中引用该库文件。

    假设有个脚本,myfuncs。里面定义了一些函数:

     1 function addem

      2 {

      3         echo $[ $1 + $2 ]

      4 }

      5

      6 function multem

      7 {

      8         echo $[ $1 * $2 ]

      9 }

     10

     11

     12 function divem

     13 {

     14         if [ $2 -ne 0 ]

     15         then

     16                 echo $[ $1 / $2 ]

     17         else

     18                 echo -1

     19         fi

     20 }

    shell函数仅在定义它的shell会话中有效。

    如果你在shell命令行界面的提示符下运行myfuncs shell脚本,shell会创建一个新的shell并在其中运行这个脚本。

    它会为那个新的shell定义这里面的函数,但当你运行另外一个要用到这些函数的脚本时,它们是无法使用的。

    如何使用:使用函数库的关键在于source命令,source命令会在当前的shell上下文中执行命令。而不是创建一个新的shell。

    source命令有个快捷的别名,称作点操作符。

    如何使用: . ./myfuncs

    这里假定在同一目录,如果不在,则需要指定相应的路径名。

    实例:

    1 #!/bin/bash

      2 . ./myfuncs

      3

      4 value1=10

      5 value2=5

      6 echo "Add Test ret = $(addem $value1 $value2)"

      7 echo "Mult Test ret = $(multem $value1 $value2)"

      8 echo "Div Test ret = $(divem $value1 $value2)"

    17.7 在命令行上使用函数

    17.7.1 在命令行上创建函数

    可以在命令行界面的提示符下直接使用函数。

    用起来就跟命令一样。而且一旦定义的函数,就可以在整个系统中使用它了,不需要管PATH环境变量了。

    例子:

     

    注意:

    1)必须在每个命令后面加上分号,这样才能知道哪里是命令的起止

    2)不能创建跟内建命令或其他命令相同的函数,否则会覆盖原来的命令

    17.7.2 在.bashrc文件中定义函数

    在命令行数定义shell函数明显的缺点是退出shell时,函数就消失了。

    解决方法:将函数定义在一个特定的位置,这个位置在每次启动一个新的shell的时候都由shell重新载入。

    最佳地点就是.bashrc。bash shell在每次启动时都会在主目录查找这个文件

    1. 直接定义函数

    直接在.bashrc后面加上

    function addem

    {

             echo $[ $1 + $2 ]

    }

    这样在系统上任意地方使用这个函数了。

    2.读取函数文件

    可以用source命令将库文件中的函数添加到.bashrc中

    直接在.bashrc后面加上

    .  /home/xcy/myfuncs

    这样就可以用myfuncs里面的函数了。

    17.8 实例

    本节介绍GNU shtool shell 脚本函数库。shtool库提供了一些简单的shell脚本库。这里暂时不写了。

  • 相关阅读:
    css 模块化
    zookeeper集群-solrcloud集群
    Ansible
    Haproxy
    Saltstack数据系统
    Saltstack入门
    DNS(bind)添加A、CNAME、MX、PTR记录、智能DNS(ACL)
    主从同步DNS(BIND)
    单台DNS服务器搭建(BIND)
    python2.7多线程的批量操作远程服务器
  • 原文地址:https://www.cnblogs.com/xcywt/p/7944596.html
Copyright © 2011-2022 走看看