Shell 语法之函数
函数是被赋予名称的脚本代码块,可以在代码的任意位置重用。每当需要在脚本中使用这样的代码块时,只需引用该代码块被赋予的函数名称。
创建函数
格式
function name {
commands
}
name 属性定义了该函数的唯一名称。name 后面要有空格。
commands 是组成函数的一条或多条 bash shell 命令。
另一种格式
name() {
commands
}
示例
#!/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"
[root@tang sh14]# ./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
This is an example of a function
Now this is the end of the script
注意:如果在函数定义之前使用函数,会得到错误消息。
如果重新定义函数,那么新定义将取代函数原先的定义。
函数返回值
默认退出状态
默认情况下,函数的退出状态是函数的最后一条命令返回的退出状态。
示例
#!/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: $?"
[root@tang sh14]# ./test4
testing the function:
trying to display a non-existent file
ls: badfile: No such file or directory
The exit status is: 2
使用 return 命令
return 命令可以使用单个整数值来定义函数退出状态,提供了一种通过编程设置函数退出状态的简单方法。
示例
#!/bin/bash
# using the return command in a function
function db1 {
read -p "Enter a value: " value
echo "doubling the value"
return $[ $value * 2]
}
db1
echo "The new value is $?"
[root@tang sh14]# ./test5
Enter a value: 10
doubling the value
The new value is 20
注意:请记住在函数完成后尽快提取返回值
请记住退出状态的取值范围是0~255
使用函数输出
正如命令输出可以捕获并存放到 shell 变量中一样,函数的输出也可以捕获并存放到 shell 变量中。
示例
#!/bin/bash
# using the echo to return a value
function db1 {
read -p "Enter a value: " value
echo $[ ($value) * 2 ]
}
result=`db1`
echo "The new value is $result"
[root@tang sh14]# ./test5b
Enter a value: 1
The new value is 2
向函数传递参数
函数可以使用标准参数环境变量来表示命令行传递给函数的参数。
函数名在变量 $0 中定义, 函数命令行的其他参数使用变量 $1、$2...,专有变量$#可以用来确定传递给函数的参数数目。
示例
#!/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
[root@tang sh14]# ./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
由于函数为自己的参数值使用专用的参数环境变量,所以函数无法从脚本命令行直接访问脚本参数值。如果想在函数中使用这些值,那么必须在调用该函数时手动传递这些数据。
示例
#!/bin/bash
# trying to access script parameters inside a function
function func7 {
echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
value=`func7 $1 $2`
echo "The result is $value"
else
echo "Usage: badtest1 a b"
fi
[root@tang sh14]# ./test7
Usage: badtest1 a b
[root@tang sh14]# ./test7 2 6
The result is 12
在函数中使用变量
全局变量是在 shell 脚本内处处有效的变量。
示例
#!/bin/bash
# using a global variable to pass a value
function db1 {
value=$[ $value * 2 ]
}
read -p "Enter a value: " value
db1
echo "The new value is: $value"
[root@tang sh14]# ./test8
Enter a value: 10
The new value is: 20
局部变量是在函数内部使用的变量,在变量声明前面冠以 local 关键字。
如果脚本在函数外部有同名变量,那么 shell 将能区分开这两个变量。
示例
#!/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
[root@tang sh14]# ./test9
The result is 22
temp is smaller
向函数传递数组
如果试图将数组变量作为函数参数使用,那么函数只提取数组变量的第一个取值。
示例
#!/bin/sh
# array variable to function test
function testit {
local newarray
newarray=("$@")
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}
[root@tang sh14]# ./test10
The original array is 1 2 3 4 5
The new array value is: 1 2 3 4 5
必须将数组变量拆分为单个元素,然后使用这些元素的值作为函数参数。
函数内部使用数组
示例
#!/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[*]}"
arg1=`echo ${myarray[*]}`
result=`addarray $arg1`
echo "The result is $result"
[root@tang sh14]# ./test11
The original array is: 1 2 3 4 5
The result is 15
从函数返回数组
示例
#!/bin/sh
# returning an array value
function 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[*]}"
[root@tang sh14]# ./test12
The original array is: 1 2 3 4 5
The new array is: 2 4 6 8 10
函数递归
示例
#!/bin/sh
# using recursion
function factorial {
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[ $1 - 1 ]
local result=`factorial $temp`
echo $[ $1 * $result ]
fi
}
read -p "Enter value: " value
result=`factorial $value`
echo "The factorial of $value is: $result"
[root@tang sh14]# ./test13
Enter value: 5
The factorial of 5 is: 120
创建库
创建函数的库文件,可以在不同脚本中引用该库文件。
其难点在于 shell 函数的作用域。与环境变量一样,shell 函数仅在其定义所处的 shell 会话中有效。如果从 shell 命令行界面运行库文件,那么 shell 将打开一个新的 shell ,并在新 shell 中运行此脚本,但是当试图运行调用这些库函数的另一个脚本时,库函数并不能使用。
使用函数库的关键是 source 命令。source 命令在当前 shell 环境中执行命令,而非创建新 shell 来执行命令。使用 source 命令在 shell 脚本内部运行库文件脚本。
source 有一个短小的别名,称为点操作符(.)
示例
#!/bin/bash
# using functions defiend 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"
[root@tang sh14]# ./test14
The result of adding them is: 15
The result of multiplying them is: 50
The result of dividing them is: 2
在命令行中使用参数
$ function divem { echo $[ $1 + $2 ]; }
$ divem 100 5
在.bashrc 文件中定义函数
将函数定义放在 shell 每次启动都能重新载入的地方,.bashrc。
可以直接定义函数,或者提供函数文件。
Shell 语法之函数的更多相关文章
- Shell 语法 if 、 case 、for 、 while、 until 、select 、repeat、子函数
if语法 : if [ expression ] then commandselif [ expression2 ] then commandselse commandsfi ...
- shell语法简单介绍
一.基本的语法 1.1.shell文件开头 shell文件必须以以下的行開始(必须方在文件的第一行): #!/bin/sh 符号#!用来告诉系统它后面的參数是用来运行该文件的程序.在这个样例中我们 ...
- centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 第三十六节课
centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 ...
- shell脚本之函数的使用
把代码封装成函数,相当于造了一个“轮子”,之后就直接重复使用即可. 函数的创建 shell中函数的创建有2种方式 1.使用function关键字 语法 function test { ... } 2. ...
- Linux Shell脚本编程-函数
函数介绍 定义:把一段独立功能的的代码当做一个整体,并为之一个名字,命名的代码段,此即为函数: 功能:函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程. 注意: ...
- shell脚本的函数介绍和使用案例
#前言:今天我们来聊聊shell脚本中的函数知识,看一下函数的优势,执行过程和相关的使用案例,我们也来看一下shell和python的函数书写方式有什么不同 #简介 .函数也具有别名类似的功能 .函数 ...
- Shell语法规范
ver:1.0 博客:https://www.cnblogs.com/Rohn 本文介绍了Shell编程的一些语法规范,主要参考依据为谷歌的Shell语法风格. 目录 背景 使用哪一种Shell 什么 ...
- shell语法习题练习进阶版
第4章 shell语法深度习题练习 4.1 使用if,case,函数的方法将服务改成system(centos6) 4.1.1 if方法 4.1.1.1 system实现 4.1.1.1.1 编写代码 ...
- 读完学会shell语法,shell脚本80%已经学会
第3章 shell语法讲解 3.1 shell运算讲解 3.1.1 运算符的讲解 3.1.2 shell运算方式的讲解 3.1.2.1 $(())运算 [root@m01 test_init] # a ...
随机推荐
- 【Composer】实战操作一:使用库
前言 前面我们简单介绍了composer的安装 以及 如何安装库 本文目的 主要实战讲解如何使用库,主要是PSR-0 和 PSR-4的区别,以及如何在代码中引用.关于PSR-0和PSR-4的具体区别可 ...
- HDFS的概念
1.数据块 每个磁盘都有默认的数据块大小,这是磁盘进行数据读/写的最小单位.构建于单个磁盘之上的文件系统通过磁盘块来管理该文件系统中的块,该文件系统块的大小可以是磁盘块的整数倍.文件系统快一半为几千字 ...
- ultraedit正则使用
下面是从UltraEdit文档中摘录的语法说明: 正则表达式 (UltraEdit 语法): 符号 功能 % 匹配行首 – 表示搜索字符串必须在行首,但不包括任何选定的结果字符中的行终止字符. $ 匹 ...
- idea使用心得(1)-快捷键用法
快捷键: Ctrl+F12,可以显示当前文件的结构,Alt+7,可在左侧生成固定框体控件,适合类复杂的情况 Ctrl+Alt+O,优化导入的类和包 Ctrl+X,删除行 删除光标所在的哪一行,对尤其是 ...
- tcpdump教程入门
tcpdump是一个最基本重要的网络分析工具, 掌握好这, 对于学习tcp/ip协议也是很有帮助的. 理解了tcp/ip协议栈的知识, 分析调优网络的能力才会更高. 所以使用tcpdump相比其它的工 ...
- 解决 Virtual Box 启动 Cannot load R0 module supLoadModule returned VERR_LDR_MISMATCH_NATIVE Failed to register ourselves as a PCI Bus (VERR_MODULE_NOT_FOUND)
返回 代码:E_FAIL (0x80004005)组件:Console界面:IConsole {8ab7c520-2442-4b66-8d74-4ff1e195d2b6} 原因: 我新建了一个vdi文 ...
- js接受url参数
1.正则表达式 function getQueryString(name) { var reg = new RegExp("(^|&)" + name + "=( ...
- PHP安全性
一.防sql注入 用户通过输入完整的字符,来和sql语句拼接成带有破坏性的sql语句,服务器执行该语句,造成破坏. 1使用mysql_real_escape_string()过滤数据,该方法在未来版本 ...
- org.apache.hadoop.security.AccessControlException: Permission denied:
org.apache.hadoop.security.AccessControlException: Permission denied: user=xxj, access=WRITE, inode= ...
- wex5 教程 之 图文讲解 可观察对象的集群应用与绑定技术
一 前言: wex5官方教程里,开篇即以一个input输入,output即时输出的例子,为我们展现了一个概念:可观察对象.在以后我的项目开发中,将大量运用可观察对象. 那么,问题来了: 1. 可观察对 ...