写在前面:案例、常用、归类、解释说明。(By Jim)

使用函数

#!/bin/bash
# testing the script function myfun {
echo "This is an example of a function"
} count=1
while [ $count -le 5 ]
do
myfun
count=$[ $count +1 ]
done
echo "This is the end of the loop"
myfun
echo "Now this is the end of the script"

(记得空格,函数一定要在使用之前定义,函数名必须唯一)

返回值
可以通过$?来确定函数的退出状态

使用return命令

#!/bin/bash
# testing the script
function myfun {
read -p "Enter a value:" value
echo "double the value"
return $[ $value * 2 ]
} myfun echo "The new vlue is $?"

结果:
Enter a value:23
double the value
The new vlue is 46
(退出状态的取值范围是0到255,$?是最近已执行命令的退出状态)

使用函数输出,这种方法最靠谱了
看例子

#!/bin/bash
# testing the script
function myfun {
read -p "Enter a value:" value
echo $[ $value * 2 ]
} result=`myfun` echo "The new vlue is $result"

(这样就能很好的利用输出结果了)

在函数中使用变量
向函数传递参数

#!/bin/bash
# testing the script
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 "Just one number 10:"
value=`addem 10`
echo $value
echo -n "No numbers:"
value=`addem`
echo $value
echo -n "More than two numbers:"
vaule=`addem 10 15 20`
echo $value

结果:
Adding 10 and 15:25
Just one number 10:20
No numbers:-1
(由上述可知,#可以得到参数的个数,1表示第一个参数,$2表示第二个参数)

#!/bin/bash
# testing the script
function addem {
if [ $# -eq 0 ]||[ $# -gt 2 ]
then
echo -1
elif [ $# -eq 1 ]
then
echo $[ $1 + $1 ]
else
echo $[ $1 + $2 ]
fi
} if [ $# -eq 2 ]
then
value=`addem $1 $2`
echo "The value is $value"
else
echo "Usage:test1 a b"
fi

(函数外面的#表示调用脚本使用的参数数,函数里的#表示调用函数使用的参数数,注意这点区别)

作用域是变量的可见区域。
全局变量,在shell脚本内处处有效的变量。函数中定义全局变量,那么主代码中有效。主代码中定义全局,函数中也有效。
默认情况下,脚本中定义的变量都是全局变量。
看例子:

#!/bin/bash
# testing the script
function myfun {
value=$[ $value * 2 ]
}
read -p "Enter a value:" value
myfun
echo "The new value is:$value"

(输入45,得到90,这里的value在函数中发生变化了,到脚本中一样可以使用,而且已经变化了)

局部变量
作用范围只在函数当中
关键字local

#!/bin/bash
# testing the script
function myfun {
local value=$[ $value * 2 ]
}
read -p "Enter a value:" value
myfun
echo "The new value is:$value"

(输入45,输出45。因为加上local关键字之后,函数中的value是局部变量,与外界无关)

#!/bin/bash
# testing the script
function myfun {
local value=$[ $value * 2 ]
echo $value
}
read -p "Enter a value:" value
result=`myfun`
echo "The new value is:$value"
echo "The result of the fun is $result"

(不过可以通过输出来获取函数处理的结果,这里的result还是处理后的结果,比如输入45,处理后是90)

数组变量与函数

#!/bin/bash
# testing the script
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[*]}"
arg=`echo ${myarray[*]}`
result=`addarray $arg`
echo "The result is $result"

结果:
The original array is :1 2 3 4 5
The result is 15
(数组参数传入函数,函数获取后,进行处理输出。脚本将输出结果打印)

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

(输出数组)

函数递归

#!/bin/bash
# testing the script
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"

(输入5,输出120。大环套小环,小环套更小,逐步执行。
我们一步一步剖析
5输入得到5*4!
4又得到4*3!
3又得到3*2!
2又得到2*1
由此得到5*4*3*2*1也就是120

显然单个脚本有助于减少输入量,但是如果多个脚本碰巧使用同样的函数又该怎样?
创建库

#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
}

使用函数库的关键词是source

#!/bin/bash
# testing the script
source ./myfuncs result=`addem 10 15`
echo "The result is $result"

(通过source就能使用库函数了)

#!/bin/bash
# testing the script
. ./myfuncs

result=`addem 10 15`
echo "The result is $result"
(或者点操作符,效果是一样的)

在命令行中使用函数
[root@localhost shellscript]# function multem {
> echo [1 * $2 ]
> }
[root@localhost shellscript]# multem 2 5
10
(多行命令)

在.bashrc文件中定义函数
直接在命令行定义shell函数的缺点是一旦退出shell,函数定义将失效。
比较省事的方法是将函数定义在shell每次启动都能重新载入的地方。.bashrc文件就是这样的地方。
可以用source(点操作符)将现有库文件的函数包含进.bashrc脚本。
重新启动命令(source .bashrc)
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific aliases and functions

function addem {
  echo [1 + $2 ]
}
(重启之后,新加入的函数就有效了)

脚本中也可以使用了

Linux&shell之高级Shell脚本编程-创建函数的更多相关文章

  1. linux shell 进阶篇、shell脚本编程-创建函数

    使用函数 #!/bin/bash # testing the script function myfun { echo "This is an example of a function&q ...

  2. Shell编程—创建函数

    1基本的脚本函数 函数是一个脚本代码块,你可以为其命名并在代码中任何位置重用.要在脚本中使用该代码块时,只要使用所起的函数名就行了. 1.1创建函数 有两种格式可以用来在bash shell脚本中创建 ...

  3. 高级Bash脚本编程指南(27):文本处理命令(三)

    高级Bash脚本编程指南(27):文本处理命令(三) 成于坚持,败于止步 处理文本和文本文件的命令 tr 字符转换过滤器. 必须使用引用或中括号, 这样做才是合理的. 引用可以阻止shell重新解释出 ...

  4. 高级Bash脚本编程(一)

    高级Bash脚本编程 Bash 它是能力很强的计算机语言,被称为解释性语言或脚本语言,它可以调用所有的UNIX命令和工具再加上公共程序. Bash中的特殊字符 注释(#) (除#!外,#!是用于指定当 ...

  5. 高级Bash脚本编程指南《Advanced Bash-Scripting Guide》 in Chinese

    <Advanced Bash-Scripting Guide> in Chinese <高级Bash脚本编程指南>Revision 10中文版 在线阅读链接:http://ww ...

  6. 高级bash脚本编程(三)

    高级bash脚本编程 知识点 compound 和 comparison -a 逻辑与 exp1 -a exp2 如果表达式 exp1 和 exp2 都为真的话,那么结果为真. -o 逻辑或 exp1 ...

  7. 高级Bash脚本编程(二)

    高级Bash脚本编程(二) 退出 退出状态码 退出:exit 被用来结束一个脚本,它也返回一个值,并且这个值会传递给脚本的父进程,父进程会使用这个值做下一步的处理. 每个命令都会返回一个退出状态码,成 ...

  8. advanced base-scripting guide in chinese(高级Bash脚本编程指南-10)

    <高级Bash脚本编程指南>Revision 10中文版 github上链接地址: https://github.com/LinuxStory/Advanced-Bash-Scriptin ...

  9. 《Advanced Bash-Scripting Guide》 in Chinese 高级Bash脚本编程指南》Revision 10中文版

    <Advanced Bash-Scripting Guide> in Chinese <高级Bash脚本编程指南>Revision 10中文版 在线阅读链接:http://ww ...

随机推荐

  1. IOS 判断日期是今天,昨天还是明天

    git地址: https://github.com/JsoonLi/NSDate-Extension   - (NSString *)compareDate:(NSDate *)date{ NSTim ...

  2. 最新 Sublime Text3 激活码 (Build 3114 有效)

    今天打开Sublime Text 3 有更新,更新了一下然后之前的激活就失效了.无奈只好重新搜索可用的激活码.不过幸运的是我搜索到了很多可用的激活码,不敢独专. // Sublime Text 3 L ...

  3. abstract和接口

    接口只包含常量和抽象方法,不能实例化. abstract: 1.抽象类不能实例化, 2.可以没有抽象方法.但有了抽象方法,一定要被定义为抽象类. 3.子类没有实现父类中所有的抽象方法.子类也必须定义为 ...

  4. 利用HTML5的Video进行视频截图并保存到本地

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  5. 39.Android版本小知识

    中文名----英文名----版本----对应API Level 棉花糖 Marshmallow - 6.0.1_r10 - API 23棉花糖 Marshmallow - 6.0.0_r5 - API ...

  6. 12.Android之Tabhost组件学习

    TabHost是整个Tab的容器,TabHost的实现有两种方式: 第一种继承TabActivity,从TabActivity中用getTabHost()方法获取TabHost.各个Tab中的内容在布 ...

  7. HD 1533 Going Home(最小费用最大流模板)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  8. 单步调试 step into/step out/step over 区别

    step into:单步执行,遇到子函数就进入并且继续单步执行(简而言之,进入子函数): step over:在单步执行时,在函数内遇到子函数时不会进入子函数内单步执行,而是将子函数整个执行完再停止, ...

  9. IE兼容模式下两个小问题,JSON.stringify和SCRIPT70 无权限

    JSON.stringify在IE兼容模式下不起作用,原来是序列化对象是一个easyuiTree的树节点对象,过于复杂的对象 SCRIPT70 权限,问题出现在获取页面iframe时: var ifr ...

  10. tomcat Host及Context 配置

    参考资料: 一.Host配置 对一个Tomcat,可以配置多台虚拟主机.简单地说,就是让一台服务器可以对应多个主机名.这在Tomcat中称之为Host.要求每个Host的Name必须唯一. 配置方法: ...