博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
创建函数
阅读量:5020 次
发布时间:2019-06-12

本文共 9101 字,大约阅读时间需要 30 分钟。

  在shell脚本编写中,通常有很多处使用相同的代码。如果这些代码比较短小,name通常并不费事。但是,如果有打断代码需要重写,则会让人厌烦,这个我们就需要使用函数来处理;

1、基本脚本函数

  函数是被富裕名称的脚本代码块,可以在代码的任意位置重复使用。引用函数的过程,我们称之为调用;

  1.1、创建函数

    在bash shell脚本中创建函数可以使用两种格式:

function name {  #name为唯一名称    commands    #commands为组成函数功能的命令}

    另外一种格式

name() {commands}

  1.2、使用函数

    相应的函数名需要在脚本中指定

#!/bin/bash# using a function in a scriptfunction func1 {    echo "This is an example of a funcation"}count=1while [ $count -le 5 ]do    func1    count=$[ $count + 1 ]doneecho "This is the end of the loop"func1echo "Now this is the end of the script"

    注意,不能在函数被定义之前去调用这个函数,会报错

#!/bin/bash# using a function located in the middle of a scriptcount=1echo "This line comes before the function definition"function func1 {    echo "This is an example of a function"}while [ $count -le 5 ]do    func1    count=$[ $count + 1 ]doneecho "This is the end of the loop"func2  #没有定义func2,所以这里会报错echo "Now this is the end of the script"

    函数的命名也需要注意,必须唯一。如果重新定义了函数,则新定义的函数就会覆盖原来的函数

#!/bin/bash# testing using a duplicate function namefunction func1 {    echo "This is first definition of the function name"}func1function func1 {  #新定义的函数就会覆盖原来的函数    echo "This is a repeat of the same function name"}func1echo "This is the end of the script"

2、返回值

  bash shell将函数看成小型的脚本,并以退出转态结束。函数退出转态有三种生成方式;

  2.1、默认退出状态

    函数的退出转态是函数的最后一条命令返回的退出状态 。可以$?来确定函数的退出状态;

#!/bin/bash# testing the exit status of a functionfunc1 () {    echo "Trying to display a non-existend file"    ls -l badfile}echo "testing the function:"func1echo "The exit status is: $?"

    这样可以知道函数执行转态为1,但是无法知道其他命令是否执行成功。

#!/bin/bash# testing the exit status of a functionfunc1 () {    ls -l badfile    echo "This was a test of a bad command"}echo "testing the functiong:"func1echo "The exit status is: $?"

    因为函数中命令位置变换,则返回的函数转态值就是0了;所以这种方式来判断函数是不正确的;

  2.2、使用return命令

    所以,我们引入了return命令来指定函数转态。return命令可以使用单个整数值来定义函数退出转态,提供了一种通过编辑设置函数退出转态的简单方法;

#!/bin/bash# using the return command in a functionfunction db1 {    read -p "Enter a value: " value    echo "doubling the value"    return $[ $value * 2 ]  #db1函数将变量$value中的用户输入值变为双倍后,通过return返回}db1echo "The new value is $?"

    注意两点:1、函数完成后尽快提取返回值;2、退出转态的取值范围是0-255;

  2.3、使用函数输出

    函数输出的结果可以给变量赋值:

    result=`db1`

    这样db1函数的值,就给了$result中

#!/bin/bash# using the echo to return a valuefunction db1 {    read -p "Enter a value: " value    echo $[ $value * 2 ]}result=`db1`echo "The new value is $result"

    这个函数使用echo语句显示计算结果,获取了db1的输出,而不是查看命令运行的状态结果;

3、在函数中使用变量

  上一个函数中的$value就是函数变量使用的方法之一,在函数中要注意变量调用;

  3.1、向函数传递参数

    $1 $2 $# 如何传递给函数呢?

#!/bin/bash# passing parameters to a functionfunction addem {    if [ $# -eq 0 ] || [ $# -gt 2 ]    then        echo -1    elif [ $# -eq 1 ]    then        echo $[ $1 + $1 ]    else        echo $[ $1 + $2 ]    fi}echo -n "Adding 10 and 15:"value=`addem 10 15`echo $valueecho -n "Let's try adding just one number: "value=`addem 10`echo $valueecho -n "Now trying adding no numbers: "value=`addem`echo $valueecho -n "Finally, try adding three numbers: "value=`addem 10 15 20`echo $value

    由于函数为自己的参数值使用专用的参数环境变量,所以函数无法从脚本命令行直接范文脚本参数值。下面的例子就是一个错误的例子:

#!/bin/bash# trying to access script parameters inside a functionfunction badfunc1 {    echo $[ $1 * $2 ]}if [ $# -eq 2 ]then     value=`badfunc1`    echo "The result is $value"else    echo "Usage: badtest1 a b"fi
./badtest1 10 15 ./badtest1: * : syntax error: operand expected (error token is "*")

    该函数使用管道变量$1和$2,不同于脚本主代码的变量$1和$2.如果想在函数中使用这些值,那么必须在调用该函数时手动传递这些数据:

#!/bin/bash# trying to access script parameters inside a functionfunction func7 {    echo $[ $1 * $2 ]}if [ $# -eq 2 ]then     value=`func7 $1 $2`  #一定要在函数中直接传递给变量;    echo "The result is $value"else    echo "Usage: badtest1 a b"fi

  3.2、在函数中处理变量

    函数中使用两种变量:1、全局变量;2、局部变量;

    1、全局变量

    shell脚本中全部地方都会生效

#!/bin/bash# using a global variable to pass avaluefunction db1 {    value=$[ $value * 2 ]}read -p "Enter a value: " valuedb1echo "The new value is: $value"

    $value在函数外部复制,同时在函数内部使用,依然生效。

    郑重做法要求程序员确切的清除函数中使用了那些变量,包括那些勇于计算值且不返回脚本的所有变量。

#!/bin/bash# demonstrating a bad use of variablesfunction func1 {    temp=$[ $value + 5 ]    result=$[ $temp * 2 ]}temp=4value=6func1echo "The result is $result"if [ $temp -gt $value ]then    echo "temp is larger"else    echo "temp is smaller"fi

    这种情况下,temp又在函数外部赋值,又在行数内部使用,所以结果可能会出人意料

    2、局部变量

    local 代表局部变量:local temp

    local temp=$[ $value + 5 ]

    local变量仅仅在函数内部使用;

#!/bin/bash# demonstrating the local keywordfunction func1 {    local temp=$[ $value + 5 ]    result=$[ $temp * 2 ]}temp=4value=6func1echo "The result is $result"if [ $temp -gt $value ]then    echo "temp is larger"else    echo "temp is smaller"fi

    这样,func1内部使用变量$temp时,脚本主代码变量$temp的值不会受到映像

4、数组变量与函数

  函数使用数组变量值需要一些技巧。

  4.1、向函数传递数组

    如果试图将数组变量作为单个参数传递,是无法正常工作的:

#!/bin/bash# trying to pass an array variablefunction testit {    echo "The parameters are: $@"    this array=$1    echo "The received array is ${thisarray[*]}"}myarray={
1 2 3 4 5}echo "The original array is: ${myarray[*]}"testit $myarray

    这时候,函数只能提取数组的一个值。

    要解决这个问题,必须将数组变量拆分为单个元素,然后使用这些元素的值作为函数参数。

#!/bin/bash# array variable to function testfunction testit {    local newarray    newarray=(`echo "$@"`)    echo "The new array value is: ${newarray[*]}"}myarray=(1 2 3 4 5)echo "The original array is ${myarray[*]}"testit ${myarray[*]}

    这时候myarray[*]就能存放数组所有的值了;函数内部可以像使用其他素组一样使用这个数组;

#!/bin/bash# adding values in an arrayfunction addarray {    local sum=0    local newarray    newarray=(`echo "$@"`)    for value in ${newarray[*]}    do        sum=$[ $sum + $value ]    done    echo $sum}myarray=(1 2 3 4 5)echo "The original array is: ${myarray[*]}"arg1=`The original array is: ${myarray[*]}`result=`addarray $arg1`echo "The result is $result"

  4.2、从函数返回数组

    使用echo语句以恰当顺序输出数组元素之,然后脚本必须将这些数据重组为新数组变量;

#!/bin/bash# returning an array valuefunction arraydblr {    local origarray    local newarray    local elements    local i    origarray=(`echo "$@"`)    newarray=(`echo "$@"`)    elements=$[ $# - 1 ]    for (( i = 0; i <= $elements; i++ ))    {        newarray[$i]=[ ${origarray[$i]} * 2 ]    }    echo ${newarray[*]}}myarray=(1 2 3 4 5)echo "The original array is: ${myarray[*]}"arg1=`echo ${myarray[*]}`result=(`arraydblr $arg1`)echo "The new array is: ${result[*]}"
./test12The original array is: 1 2 3 4 5The new array is: 2 4 6 8 10

5、函数递归

  递归调用函数是指函数调用自身进行求解。递归的一个经典案例是计算阶乘;

  5!=1*2*3*4*5=120

  这个就可以显示为:x!=x*(x-1)!

  这就可以以脚本的形式展现出来:

function factorial {    if [ $1 -eq 1 ]    then        echo 1    else        local temp=$[ $1 - 1 ]        local result=`factorial $temp`        echo $[ $result * $1 ]    fi}

  该阶乘函数调用自身进行计算:

#!/bin/bash# using recursionfunction factorial {    if [ $1 -eq 1 ]    then        echo 1    else        local temp=$[ $1 - 1 ]        local result=`factorial $temp`        echo $[ $result * $1 ]    fi}read -p "Enter value: " valueresult=`factorial $value`echo "The factorial of $value is: $result"

6、创建库

  多个脚本使用同样的函数,这时候我们就需要创建库文件才行;

# my script functionsfunction addem {    echo $[ $1 + $2 ]}function multem {    echo $[ $1 + $2 ]}function divem {    if [ $2 -ne 0 ]    then        echo $[ $1 / $2 ]    else        echo -1    fi}

  下一步将这个文件包含进需要调研的库函数中

  问题:如果从shell命令行界面运行myfuncs脚本,nameshell将打开一个新shell,并在该新shell中运行脚本。这将为新shell定义3个函数,但是当试图运行调用这些函数的另一个脚本时,库函数并不使用;

#!/bin/bash# using a library file the wrong way./myfuncsresult=`addem 10 50`echo "The result is $result"

  使用函数库的关键命令时source命令。使用source命令再shell脚本内部运行库文件脚本。这样脚本就可以使用这些函数。

#!/bin/bash# using functions defined in a library file. ./myfuncsvalue1=10value2=5result1=`addem $value1 $value2`result2=`multem $value1 $value2`result3=`divem $value1 $value2`echo "The result of adding them is: $result1"echo "The result of multiplying them is: $result2"echo "The result of dividing them is: $result3"

7、在命令行中使用函数

  函数可以使用在外面命令行中

  7.1、在命令行创建函数

    两种方法:

    1、将函数定义在一行命令中:

    $ function divem { echo $[ $1 / $2 ]; }

    $ divem 100 5

    在命令行中定义函数,每条命令后面必须用分号隔开;

    $ funtion doubleit { read -p "Enter value: " value; echo $[ $value * 2 ]; }

    $ doubleit

    2、使用多行命令定义函数。这样,bash shell使用次级命令提示符输入更多的命令

    $ function multem {

    > echo $[ $1 * $2 ]

    > }

    $ multem 2 5

    10

    $

  7.2、在.bashrc文件中定义函数

    在命令行下定义函数,一退出,就不能继续运行了。所以我们可以在.bashrc文件中来定义;

    1、直接定义函数

$ cat .bashrc# .bashrc# Source global definitionsif [ -r /etc/bashrc ]; then        . /etc/bashrcfifunction addem {echo $[ $1 + $2 ]}

    2、提供函数文件

    正如shell脚本中的做法一样,可以使用source命令(点操作符),将库文件的函数包含进.bashrc脚本:

$ cat .bashrc# .bashrc# Source global definitionsif [ -r /etc/bashrc ]; then        . /etc/bashrcfi. /home/rich/libraries/myfuncs

    确保库文件的准确路径,这样bash shell才能够找到库文件。再次启动shell之后,该库的所有函数将都能在命令行界面使用;

    更好的是,shell还将全部已定义函数传递给子shell进程。这样从shell会话运行的脚本,自定义函数随之可用。

#!/bin/bash# using a function defined in the .bashrc filevalue1=10value2=5result1=`addem $value1 $value2`result2=`multem $value1 $value2`result3=`divem $value1 $value2`echo "The result of adding them is: $result1"echo "The result of multiplying them is: $result2"echo "The result of dividing them is: $result3"

 

    

转载于:https://www.cnblogs.com/BurnovBlog/p/10799057.html

你可能感兴趣的文章
Spring Boot RestTemplate文件上传
查看>>
myBatis自动生成mapping,dao和model
查看>>
Android Serivce 高级篇AIDL讲解
查看>>
SpringBoot学习笔记(2):引入Spring Security
查看>>
图片加水印 PDF取缩略图
查看>>
bzoj 4180: 字符串计数
查看>>
安卓--布局设计-计算器
查看>>
Java重写《C经典100题》 --27
查看>>
ABP中的拦截器之EntityHistoryInterceptor
查看>>
【oracle】oracle数据库建立序列、使用序列实现主键自增
查看>>
使用SQLiteDatabase操作SQLite数据库第二种方法
查看>>
vue,一路走来(12)--父与子之间传参
查看>>
实现交换两个变量值的第二种方法
查看>>
英语单词学习备忘转载
查看>>
【C++】单例模式详解
查看>>
文本框根据关键字异步搜索内容
查看>>
SQLServer 基本语法
查看>>
python模块之multiprocessing模块, threading模块, concurrent.futures模块
查看>>
PHP 的 HMAC_SHA1算法 实现
查看>>
深入理解javascript原型和闭包_____全部
查看>>