第十六章:创建函数

基本的脚本函数

创建函数

1.用function关键字,后面跟函数名

function name {
commands
}

2.函数名后面跟空圆括号,标明正在定义一个函数

name() {
commands
}

如果两个函数的名称相同,那么后面的将会覆盖前面的,而且不会有提示。

使用函数

使用函数名称即可。必须先定义,再使用。

#!/bin/bash
f1() {
echo "this is f1."
}
f1 function f1 {
echo "this is f1111."
}
f1 f2
f2() {
echo "this is f2."
}

这里首先定义了f1,然后执行,然后又定义了一个f1,再执行。发现第二次执行的是新的f1函数。

接着调用f2,由于此时f2还没有定义,所以会调用失败。

$ function_test
this is f1.
this is f1111.
./function_test: line 12: f2: command not found

返回值

bash shell会把函数当做小型脚本,运行结束时会返回一个退出状态码。

有三种方式生成函数退出状态码

默认退出状态码

默认情况下,函数的退出状态码是函数中最后一条命令返回的退出状态码

函数执行结束后,可以使用$?变量来决定函数的退出状态码

#!/bin/bash
fun(){
ls nothing
echo $?
echo "done"
} fun
echo "fun:$?"

由于ls找不到nothing文件或者目录,所以返回的状态码=2

但是fun函数最后的echo执行成功了,所以fun返回的状态码=0

$ function_test
ls: cannot access nothing: No such file or directory
2
done
fun:0

使用函数默认退出状态码是很危险的……

使用return命令

bash shell使用return命令退出函数并返回特定的退出状态码。

return命令允许指定一个整数值来定义函数的退出状态码

注意:函数一结束就取返回值,退出状态码必须在0-255之间。

使用函数输出

可以将函数的输出保存到变量中,例如:

result=`f1`

bash shell不会将read读取输入的部分作为 STDOUT

在函数中使用变量

向函数传递参数

在脚本中指定函数时,必须将参数和函数放在同一行

然后函数可以用参数环境变量来获得参数值

在函数中处理变量

函数会用到全局变量和局部变量。

全局变量

在脚本中定义的所有变量均为全局变量。

#!/bin/bash
var=1
fun(){
echo "var:"$var
var2=2
} fun
echo "var2:"$var2

输出:

$ function_test
var:1
var2:2

局部变量

函数内部任何变量都可以声明为局部变量,只需在变量前加local关键字即可。

在脚本中定义的局部变量,函数中是无法访问的。

数组变量和函数

向函数传递数组参数

需要将数组变量的值分解成单个值,然后作为函数参数使用。

在函数内部,可以将他们再组成一个数组。

#!/bin/bash
array=(a b c d) fun(){
newarray=($@) #重新组合为数组
echo "newarray is:"${newarray[*]} #打印数组
echo "The 3rd element is:"${newarray[3]}
} fun ${array[*]} #拆分成多个值传入

输出:

$ function_test
newarray is:a b c d
The 3rd element is:d

如果试图将数组当做一个参数传递给函数,那么函数只会读取数组变量的第一个值。

#!/bin/bash
array=(a b c d) fun(){
echo "We have "$#" parameter(s)."
echo "They are: "$@
echo "They are: "$*
} fun $array

fun函数只认识数组中的第一个元素

$ function_test
We have 1 parameter(s).
They are: a
They are: a

从函数返回数组

#!/bin/bash
fun(){
local array=(a b c d)
echo ${array[*]}
} array=(`fun`)
echo ${array[2]}

同返回普通字符串类似,按顺序echo输出,然后放在圆括号里面即可。

函数递归

还是以最简单的求N的阶乘为例:

#!/bin/bash
fun(){
local result=1;
if [ $1 -eq 1 ]
then
echo 1
else
result=$[$1 * `fun $[$1 - 1]`]
echo $result
fi
} fun $1

没有新的知识点,只是不太熟悉罢了

如果使用了``,那么函数内的echo就不会输出到STDOUT了,和上面其他的例子一样。

创建库

source命令可以在当前的shell上下文中执行命令,而不是创建一个新的shell来执行命令。可以用source命令来在shell脚本中运行库文件脚本。

source命令等同于点操作符(dot operator)

在一个名叫lib_test的文件中定义一个plus函数

#!/bin/bash
plus(){
if [ $# -ne 2 ]
then
echo "I need 2 numbers!"
return
fi
echo $[$1 + $2]
}

然后我们在另一个脚本中使用它

#!/bin/bash
. lib_test #脚本路径
plus $1 $2

使用方法很简单,这样就相当于把lib_test导入到当前文件中了

$ function_test 4 5
9

在命令行上使用函数

在命令行上创建函数

由于在键入命令时shell就会解释命令,所以可以在命令上直接定义函数。

$ plus(){ echo $[$1 + $2]; }
$ plus 3 1
4

注意:要在花括号两边加空格,每条命令用分号隔开。

下面的方法看起来更实用一些,效果也更好

$ plus(){
> echo $[$1 + $2]
> }
$ plus 4234 23
4257

无须分号和空格。

在.bashrc文件中定义函数

可以直接在这里定义函数,也可以使用source命令,导入库

注意,修改了.bashrc之后要重启才能生效

如果不是每次开机都要执行,那我们还可以在shell中直接使用source,很多时候,这种方式可能更好一些。

转贴请保留以下链接

本人blog地址

http://su1216.iteye.com/

http://blog.csdn.net/su1216/

《Linux命令行与shell脚本编程大全》 第十六章 学习笔记的更多相关文章

  1. 《Linux命令行与shell脚本编程大全》 第二十七章 学习笔记

    第二十七章:shell脚本编程进阶 监测系统统计数据 系统快照报告 1.运行时间 uptime命令会提供以下基本信息: 当前时间 系统运行的天数,小时数,分钟数 当前登录到系统的用户数 1分钟,5分钟 ...

  2. 《Linux命令行与shell脚本编程大全》 第二十三章 学习笔记

    第二十三章:使用数据库 MySQL数据库 MySQL客户端界面 mysql命令行参数 参数 描述 -A 禁用自动重新生成哈希表 -b 禁用 出错后的beep声 -B 不使用历史文件 -C 压缩客户端和 ...

  3. 《Linux命令行与shell脚本编程大全》 第三章 学习笔记

    第三章:基本的bash shell命令 bash程序使用命令行参数来修改所启动shell的类型 参数 描述 -c string 从string中读取命令并处理他们 -r 启动限制性shell,限制用户 ...

  4. 《Linux命令行与shell脚本编程大全》 第六章环境变量

    很多程序和脚本都通过环境变量来获取系统信息.存储临时数据和配置信息. 6.1 什么是环境变量: bash shell用一个叫环境变量(environment variable)的特性来存储有关shel ...

  5. 《Linux命令行与shell脚本编程大全》第十三章 更多的结构化命令

    本章讨论bash shell的循环命令for.while和until 13.1 for命令 重复执行一系列命令在编程中很常见. bash shell提供了for命令,允许你创建一个遍历一系列值的循环. ...

  6. 《Linux命令行与shell脚本编程大全》第二十一章 sed进阶

    本章介绍一些sed编辑器提供的高级特性. 21.1 多行命令 按照之前的知识,所有的sed编辑器命令都是针对单行数据执行操作的. 在sed编辑器读取数据流时,它会基于换行符的位置将数据分成行,一次处理 ...

  7. 《Linux命令行与shell脚本编程大全》第十一章 构建基本脚本

    11.1使用多个命令 $date;who   //  命令列表,加入分号就可以,这样会依次执行.参见5.2.1节 注意区分$(date;who),这个是进程列表,会生成一个子shell来执行 Shel ...

  8. 《Linux命令行与Shell脚本编程大全第2版》读书笔记

    公司说不准用云笔记了,吓得我赶紧把笔记贴到博客上先..... 近3年前的了,只有一半的章节,后面的没空记录了.... 第1章 可以cat /proc/meminfo文件来观察Linux系统上虚拟内存的 ...

  9. 《Linux命令行与shell脚本编程大全》第十七章 创建函数

    可以将shell脚本代码放进函数中封装起来,这样就能在脚本中的任何地方多次使用它了. 17.1 基本的脚本函数 函数:是一个脚本代码块,可以为其命名并在代码中任何位置重用. 17.1.1 创建函数 有 ...

  10. 《Linux命令行与shell脚本编程大全》 第五章理解shell

    5.1 1. cat /etc/passwd 可以查看每个用户自己的默认的shell程序. 2.默认的交互shell会在用户登录某个虚拟控制台终端时启动. 不过还有另外一个默认的shell是/bin/ ...

随机推荐

  1. 微软HR泄露的asp.net面试题

    1.面向对象的思想主要包括什么? 2.什么是ASP.net中的用户控件? 3.什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载? 4.列举一下你所了解的XML技术及 ...

  2. Servlet的学习之Session(2)

    在上一篇中我们学习了Session对象默认在一个会话过程中,由服务器创建,能保存在这个会话过程中用户访问多个web资源时产生的需要保存的数据,并在访问服务器中其他web资源时可以将这些数据从Sessi ...

  3. Android开源框架AsyncHttpClient (android-async-http)使用

    android-async-http 开源框架可以使我们轻松地获取网络数据或者向服务器发送数据,最关键的是,它是异步框架,在底层使用线程池处理并发请求,效率很高,使用又特别简单. 以往我们在安卓上做项 ...

  4. 快速排序的时间复杂度nlogn是如何推导的??

    本文以快速排序为例,推导了快排的时间复杂度nlogn是如何得来的,其它算法与其类似. 对数据Data = { x1, x2... xn }: T(n)是QuickSort(n)消耗的时间: P(n)是 ...

  5. 百度贴吧客户端(Android)网络通信行为分析

    百度贴吧安卓客户端网络通信行为分析 本文由CSDN-蚍蜉撼青松[主页:http://blog.csdn.net/howeverpf]原创,转载请注明出处! 一.实验环境与结果概述 1.1 实验环境   ...

  6. 在tornado中使用celery实现异步任务处理之中的一个

    一.简单介绍 tornado-celery是用于Tornado web框架的非堵塞 celeryclient. 通过tornado-celery能够将耗时任务增加到任务队列中处理, 在celery中创 ...

  7. DELPHI SOKET 编程(使用TServerSocket和TClientSocket)

    本文采用delphi7+TServerSocket+TClientSocket; 笔者在工作中遇到对局域网中各工作站与服务器之间进行Socket通信的问题.现在将本人总结出来的TServerSocke ...

  8. C++ Map 容器

    1.Map是c++的一个标准容器,它提供了很好一对一的关系. Map是一种关联是容器,在map中增加和删除元素非常容易.可以修改一个特定的节点而不对其他节点不产生影响,由于map是一种关联式容器,Ke ...

  9. LCD显示--Ht1621b芯片显示屏驱动

    Ht1621b芯片显示屏驱动 关于HT1621b芯片的具体信息能够參考数据手冊上的内容:百度文库HT1621b中文资料 CS : 片选输入接一上拉电阻当/CS 为高电平读写HT1621的数据和命令无效 ...

  10. HW Video Acceleration in Chrome/Chromium HTML5 video 视频播放硬件加速

    Introduction Video decode (e.g. YouTube playback) and encode (e.g. video chat applications) are some ...