Shell编程—创建函数
1基本的脚本函数
函数是一个脚本代码块,你可以为其命名并在代码中任何位置重用。要在脚本中使用该代码块时,只要使用所起的函数名就行了。
1.1创建函数
有两种格式可以用来在bash shell脚本中创建函数。第一种格式采用关键字function,后跟分配给该代码块的函数名。
function name {
commands
}
二种格式更接近于其他编程语言中定义函数的方式。
name() {
commands
}
1.2 使用函数
$ cat test1
#!/bin/bash
# using a function in a script
function func1 {
echo "This is an example of a function"
}
count=1
while [ $count -le 5 ]
do
func1
count=$[ $count + 1 ]
done
echo "This is the end of the loop"
func1
echo "Now this is the end of the script" $ ./test1
This is an example of a function
This is an example of a function
This is an example of a function
This is an example of a function
This is an example of a function
This is the end of the loop
函数定义的位置一定要在使用到该函数的位置之前。
2返回值
2.1默认退出状态码
默认情况下,函数的退出状态码是函数中最后一条命令返回的退出状态码。在函数执行结束后,可以用标准变量$?来确定函数的退出状态码。
$ cat test4
#!/bin/bash
# testing the exit status of a function
func1() {
echo "trying to display a non-existent file"
ls -l badfile
}
echo "testing the function: "
func1
echo "The exit status is: $?" $ ./test4
testing the function:
trying to display a non-existent file
ls: badfile: No such file or directory
The exit status is: 1
函数的退出状态码是1,这是因为函数中的最后一条命令没有成功运行。但你无法知道函数中其他命令中是否成功运行。看下面的例子:
$ cat test4b
#!/bin/bash
# testing the exit status of a function
func1() {
ls -l badfile
echo "This was a test of a bad command"
}
echo "testing the function:"
func1
echo "The exit status is: $?" $ ./test4b
testing the function:
ls: badfile: No such file or directory
This was a test of a bad command
The exit status is: 0
这次,由于函数最后一条语句echo运行成功,该函数的退出状态码就是0,尽管其中有一条命令并没有正常运行。
2.2使用return命令
return命令来退出函数并返回特定的退出状态码。return命令允许指定一个整数值来定义函数的退出状态码,从而提供了一种简单的途径来编程设定函数退出状态码。
$ cat test5
#!/bin/bash
# using the return command in a function
function dbl {
read -p "Enter a value: " value
echo "doubling the value"
return $[ $value * 2 ]
}
dbl
echo "The new value is $?"
dbl函数会将$value变量中用户输入的值翻倍,然后用return命令返回结果。脚本用$?变量显示了该值。
但当用这种方法从函数中返回值时,要小心了。记住下面两条技巧来避免问题:
- 函数一结束就取返回值;
- 退出状态码必须是0~255。
例如我们运行一下:
$ ./test5
Enter a value: 200
doubling the value
The new value is 144
2.3使用函数输出
可以用下面这种方法来获得任何类型的函数输出,并将其保存到变量中:
result=$(dbl)
3在函数中使用变量
3.1 向函数传递参数
函数可以使用标准的参数环境变量来表示命令行上传给函数的参数。例如,函数名会在$0 变量中定义,函数命令行上的任何参数都会通过$1、$2等定义。也可以用特殊变量$#来判断传给函数的参数数目。
在脚本中指定函数时,必须将参数和函数放在同一行,像这样:
func1 $value1 10
然后函数可以用参数环境变量来获得参数值。这里有个使用此方法向函数传值的例子。
$ cat test6
#!/bin/bash
# passing parameters to a function
function 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 $value
echo -n "Let's try adding just one number: "
value=$(addem 10)
echo $value
echo -n "Now trying adding no numbers: "
value=$(addem)
echo $value
echo -n "Finally, try adding three numbers: "
value=$(addem 10 15 20)
echo $value $ ./test6
Adding 10 and 15: 25
Let's try adding just one number: 20
Now trying adding no numbers: -1
Finally, try adding three numbers: -1
由于函数使用特殊参数环境变量作为自己的参数值,因此它无法直接获取脚本在命令行中的参数值。
3.2在函数中处理变量
函数使用两种类型的变量:
- 全局变量
- 局部变量
默认情况下,你在脚本中定义的任何变量都是全局变量。在函数外定义的变量可在函数内正常访问:
$ cat test8
#!/bin/bash
# using a global variable to pass a value
function dbl {
value=$[ $value * 2 ]
}
read -p "Enter a value: " value
dbl
echo "The new value is: $value" $ ./test8
Enter a value: 450
The new value is: 900
函数内部使用的任何变量都可以被声明成局部变量。要实现这一点,只要在变量声明的前面加上local关键字就可以了。
$ cat test9
#!/bin/bash
# demonstrating the local keyword
function func1 {
local temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then
echo "temp is larger"
else
echo "temp is smaller"
fi $ ./test9
The result is 22
temp is smaller
4数组变量和函数
4.1 向函数传数组参数
如果你试图将该数组变量作为函数参数,函数只会取数组变量的第一个值。要解决这个问题,你必须将该数组变量的值分解成单个的值,然后将这些值作为函数参数使用。在函数内部,可以将所有的参数重新组合成一个新的变量。下面是个具体的例子:
$ cat test10
#!/bin/bash
# array variable to function test
function 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[*]} $ ./test10
The original array is 1 2 3 4 5
The new array value is: 1 2 3 4 5
该脚本用$myarray变量来保存所有的数组元素,然后将它们都放在函数的命令行上。该函数随后从命令行参数中重建数组变量。在函数内部,数组仍然可以像其他数组一样使用。
$ cat test11
#!/bin/bash
# adding values in an array
function 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[*]}"
result=$(addarray ${myarray[*]})
echo "The result is $result" $ ./test11
The original array is: 1 2 3 4 5
The result is 15
addarray函数会遍历所有的数组元素,将它们累加在一起。你可以在myarray数组变量中放置任意多的值,addarry函数会将它们都加起来。
4.2从函数返回数组
从函数里向shell脚本传回数组变量也用类似的方法。函数用echo语句来按正确顺序输出单个数组值,然后脚本再将它们重新放进一个新的数组变量中。
#!/bin/bash
function test {
local array
local newarray
array=($(echo "$@"))
sum=0
for val in ${array[*]}
do
newarray[$sum]=$[$val*2]
sum=$[$sum+1]
done
echo ${newarray[*]}
}
myarray=(1 2 3 4 5)
echo "array: ${myarray[*]}"
array=$(test ${myarray[*]})
echo ${array[*]} $ ./test12
array: 1 2 3 4 5
2 4 6 8 10
5函数递归
$ cat test13
#!/bin/bash
# using recursion
function 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: " value
result=$(factorial $value)
echo "The factorial of $value is: $result" $ ./test13
Enter value: 5
The factorial of 5 is: 120
6创建库
使用函数可以在脚本中省去一些输入工作,这一点是显而易见的。但如果你碰巧要在多个脚本中使用同一段代码呢?显然,为了使用一次而在每个脚本中都定义同样的函数太过麻烦。有个方法能解决这个问题!bash shell允许创建函数库文件,然后在多个脚本中引用该库文件。
第一步是创建一个包含脚本中所需函数的公用库文件
$ cat myfuncs
# my script functions
function addem {
echo $[ $1 + $2 ]
}
function multem {
echo $[ $1 * $2 ]
}
function divem {
if [ $2 -ne 0 ]
then
echo $[ $1 / $2 ]
else
echo -1
fi
}
第二步是在用到这些函数的脚本文件中包含myfuncs库文件。(用source命令)
使用函数库的关键在于source命令。source命令有个快捷的别名,称作点操作符。要在shell脚本中运行myfuncs 库文件,只需添加下面这行:
. ./myfuncs
所以,这里有个用myfuncs库文件创建脚本的例子:
$ cat test14
#!/bin/bash
# using functions defined in a library file
. ./myfuncs
value1=10
value2=5
result1=$(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" $ ./test14
The result of adding them is: 15
The result of multiplying them is: 50
The result of dividing them is: 2
7在命令行上使用函数
7.1在命令行上创建函数
因为shell会解释用户输入的命令,所以可以在命令行上直接定义一个函数。有两种方法。
一种方法是采用单行方式定义函数。
$ function divem { echo $[ $1 / $2 ]; }
$ divem 100 5
20
当在命令行上定义函数时,你必须记得在每个命令后面加个分号,这样shell就能知道在哪里是命令的起止了。
$ function divem { echo $[ $1 / $2 ]; }
$ divem 100 5
20
另一种方法是采用多行方式来定义函数。在定义时,bash shell会使用次提示符来提示输入更多命令。用这种方法,你不用在每条命令的末尾放一个分号,只要按下回车键就行:
$ function multem {
> echo $[ $1 * $2 ]
> }
$ multem 2 5
10
在函数的尾部使用花括号,shell就会知道你已经完成了函数的定义。
7.2在.bashrc 文件中定义函数
bash shell在每次启动时都会在主目录下查找这个文件,所以把函数写在.bashrc文件里面,每次启动一个新shell的时候,都会由shell重新载入。
1. 直接定义函数
$ cat .bashrc
# .bashrc
# Source global definitions
if [ -r /etc/bashrc ]; then
. /etc/bashrc
fi function addem {
echo $[ $1 + $2 ]
}
$ cat .bashrc
# .bashrc
# Source global definitions
if [ -r /etc/bashrc ]; then
. /etc/bashrc
2. 读取函数文件
$ cat .bashrc
# .bashrc
# Source global definitions
if [ -r /etc/bashrc ]; then
. /etc/bashrc
fi . /home/rich/libraries/myfuncs
Shell编程—创建函数的更多相关文章
- shell高级-----创建函数
基本脚本函数 1.创建函数 有两种格式可以用来在bash shell脚本中创建函数.第一种采用关键字function.后跟分配给该代码的函数名. function name { commands } ...
- mysql编程--创建函数出错的解决方案
本文章转载自:http://www.jb51.net/article/71100.htm 在使用MySQL数据库时,有时会遇到MySQL函数不能创建的情况.下面就教您一个解决MySQL函数不能创建问题 ...
- shell编程之函数
一.函数定义和调用 函数是Shell脚本中自定义的一系列执行命令,一般来说函数应该设置有返回值(正确返回0,错误返回非0).对于错误返回,可以定义其他非0正值来细化错误.使用函数最大的好处是可避免出现 ...
- Linux&shell之高级Shell脚本编程-创建函数
写在前面:案例.常用.归类.解释说明.(By Jim) 使用函数 #!/bin/bash # testing the script function myfun { echo "This i ...
- linux shell 进阶篇、shell脚本编程-创建函数
使用函数 #!/bin/bash # testing the script function myfun { echo "This is an example of a function&q ...
- shell编程 之 函数
1 函数基本格式 个人认为,编程中的函数基本上有3种,第一种是糖葫芦函数,一根棒棒串起来,执行一次就是走个过场,吃完了糖葫芦就没别的事了,第一种基本就是这样的: 它没有参数,没有返回值. demoFu ...
- Linux - 简明Shell编程08 - 函数(Function)
脚本地址 https://github.com/anliven/L-Shell/tree/master/Shell-Basics 示例脚本及注释 #!/bin/bash function Check( ...
- shell 编程之函数
shell 函数的定义和普通的c语言函数定义差不多 function(){ } shell 函数的返回值,可以显示的return 语句,如果没有return 那么就会把最后一条语句的执行结果作为返回 ...
- Shell 编程(函数)
声明函数 demoFun(){ echo "这是我的第一个 shell 函数!" } 函数名(){ ...函数体 } 在Shell中,调用函数时可以向其传递参数.在函数体内部,通过 ...
随机推荐
- Python os.fstat() 方法
概述 os.fstat() 方法用于返回文件描述符fd的状态,类似 stat().高佣联盟 www.cgewang.com Unix,Windows上可用. fstat 方法返回的结构: st_dev ...
- PHP strptime() 函数
------------恢复内容开始------------ 实例 解析由 strftime() 生成的时间/日期: <?php$format="%d/%m/%Y %H:%M:%S&q ...
- luogu P5161 WD与数列 SAM 线段树合并 启发式合并
LINK:WD与数列 这道题可谓妙绝 我明白了一个增量统计的原理. 原本的想法是:差分之后 显然长度为1的单独统计 长度为2的以及更多就是字符串之间的匹配问题了. 对差分序列建立SAM 由于第一个是一 ...
- ABAP 动态备份自建表数据到新表(自建表有数据的情况下要改字段长度或者其他)
当abaper开发好一个程序给用户使用一段时间后,发现某个字段的长度需要修改,但数据库表中已经存在很多数据,冒然直接改表字段可能会导致数据丢失,这种问题的后果可能非常严重. 所以我想到先复制出一个新表 ...
- 账本APP服务器端开发
账本APP开发 好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 上一篇文章我们聊 ...
- C++STL算法
1.不变序列算法 不会修改算法所作用的容器或对象 适用于顺序容器和关联容器,时间复杂度为O(n). 2.变值算法 会修改源区间或目标区间元素的值,值被修改的那个区间,不可属于关联容器. 3.删除算法 ...
- Qt自定义控件之仪表盘3--雷达扫描图
1.设计思想 雷达扫描图,在影视作品中见到较多,比如飞机雷达.舰艇雷达,有一个扫描线转圈代表雷达一周旋转或一个批次的收发,发现目标就在表盘上标记位置.和汽车仪表盘类似,汽车仪表盘有底盘背景图.同圆.刻 ...
- 100例Python代码带你从入门到进阶!
以下所有代码全都至少运行一遍,确保可复现.易于理解.逐步完成入门到进阶的学习. 此教程经过我 反复打磨多遍 ,经常为此熬夜,真心不易,文章比较长,看完有用,帮我点个在看或分享支持. 教程包括 62 个 ...
- 强开企业付款到零钱与现金红包,无需等待90/30天,2-12H即可强开通!
一.微信官方给出的,企业付款到零钱|现金红包开通的说明 针对入账方式为即时入账至商户号,结算周期为T+1的商户,需满足三个条件:1)入驻满90天,2)连续正常交易30天,3)保持正常健康交易.其余结算 ...
- FreeAnchor 国科大