linux之函数
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里面的函数了。
linux之函数的更多相关文章
- Linux open函数
Linux open函数 open 函数用于打开和创建文件.以下是 open 函数的简单描述 #include <fcntl.h> int open(const char *pathnam ...
- linux内核函数库文件的寻找
linux内核函数的so库文件怎么找呢? 首先还是要产生一个进程的coredump文件的 linux有一个lib-gdb.so库,这个进程的coredump文件中所有load段的最后一个load段中, ...
- linux select函数详解
linux select函数详解 在Linux中,我们可以使用select函数实现I/O端口的复用,传递给 select函数的参数会告诉内核: •我们所关心的文件描述符 •对每个描述符,我们所关心的状 ...
- Linux mmap函数简介
一.简介 Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改, 先来看一下mmap的函数声明: 头文件: ...
- 动态替换Linux核心函数的原理和实现
转载:https://www.ibm.com/developerworks/cn/linux/l-knldebug/ 动态替换Linux核心函数的原理和实现 在调试Linux核心模块时,有时需要能够实 ...
- Linux getopt()函数 getopt_long()函数---转
http://hi.baidu.com/scoundrelgg/item/d4083f8412eea05d26ebd97f Linux getopt()函数 getopt_long()函数 get_o ...
- linux 系统函数之 (dirname, basename)【转】
转自:http://blog.csdn.net/peter_cloud/article/details/9308333 版权声明:本文为博主原创文章,未经博主允许不得转载. 除非你的原件考虑跨平台. ...
- linux C函数之strdup函数分析【转】
本文转载自:http://blog.csdn.net/tigerjibo/article/details/12784823 linux C函数之strdup函数分析 一.函数分析 1.函数原型: #i ...
- [ARM-Linux开发]Linux open函数
Linux open函数 open 函数用于打开和创建文件.以下是 open 函数的简单描述 #include <fcntl.h> int open(const char *pathnam ...
- linux execl()函数 关于execl()函数族的用法不在赘述,
linux execl()函数 关于execl()函数族的用法不在赘述, linux 网络编程 1---(基本概念) 1.TCP和UDP协议 共同点:同为传输层协议 不同点: TCP:有连接,可靠 U ...
随机推荐
- 手写promise
写在前面: 在目前的前端分开中,我们对于异步方法的使用越来越频繁,那么如果处理异步方法的返回结果,如果优雅的进行异步处理对于一个合格的前端开发者而言就显得尤为重要,其中在面试中被问道最多的就是对Pro ...
- SpringVC 拦截器+自定义注解 实现权限拦截
1.springmvc配置文件中配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns= ...
- Python 格式化
数字前面补0 字符型: print('23'.zfill(5)) 数字型: print('%011d' % 124) 日期与str互转: datetime 转 str str_date = datet ...
- 虚拟机中配置SQL SERVER2008R2远程访问
VM虚拟机中配置数据库访问 选择虚拟机设置--硬件--网络适配器,选择桥接模式:直接连接物理网络 不可选用主机模式(与主机共享专用网络) 数据库远程配置,转自:http://jingyan.baidu ...
- oracle for update和for update nowait 的区别
原文地址:http://www.cnblogs.com/quanweiru/archive/2012/11/09/2762223.html 1.for update 和 for update nowa ...
- Diycode开源项目 Glide图片加载分析
1.使用Glide前的准备 1.1.首先要build.gradle中添加 github原地址点击我. 参考博客:Glide-开始! 参考博客:android图片加载库Glide的使用介绍. 参考博 ...
- sql:where中多种状况简便写法
字段名:Bran,block,are ,store 四个字段中存在值等于0或者不等于0,两种情况.where中如果用if等条件判断会有16中组合,如果采用where中的条件就避免了这个情况. decl ...
- python基础——18(面向对象2+异常处理)
一.组合 自定义类的对象作为另一个类的属性. class Teacher: def __init__(self,name,age): self.name = name self.age = age t ...
- tensorboard在cmd运行成功但在浏览器中不能正常显示的问题解决
我是配置了两个python环境,python3.5和anconda3.5,强烈建议使用python3.5版本,算是比较稳定的! cmd在运行时是按顺序查找的文件,如果说是python3.6这个版本问 ...
- mac攻略(九) -- ssh工具secureCRT
mac ssh 客户端 : 本身mac直接使用终端来ssh连接就很方便,但是使用过程中随着远程服务器的增多和zsh和远程服务器编码不同产生了乱码,决定安装一款ssh终端软件,以下方法亲测可用,感谢提供 ...