原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://twentyfour.blog.51cto.com/945260/525126

知识体系:

#创建函数

#使用参数

#共享函数

shell脚本代码可以封装在函数内,而函数可以在脚本任意处使用,由此减少大段代码的重复编写。

1、基本脚本函数
函数是被赋予名称的脚本代码块,可以在代码的任意位置使用。当需要调用代码块的时候,只需引用代码块被赋予的函数名即可。

1.1、创建函数

在bash shell脚本中创建函数可以使用两种方式:

*关键字function,基本格式为:

function name{

commands

}

*()方式:

name() {

commands

}

下面就对这两种方式举例创建.

1.2、使用函数

如下采用上面创建函数的两种方式举例:

[root@wzp ~]# chmod u+x 7.1test

[root@wzp ~]# cat 7.1test

#!/bin/bash

function fun1 {

echo  "this is the first
function"

}

fun1

fun2() {

echo  "this is the second
function"

}

fun2

[root@wzp ~]# ./7.1test

this is the first function

this is the second function
这里头有两个函数名:fun1和fun2,对应两个函数执行后显示不同结果。

但是有点要注意的是必须先定义好函数,后才能调用,看个例子先:
[root@wzp
~]# cat 7.1test

#!/bin/bash

function fun1 {

echo  "this is the first
function"

}

fun1

fun2

fun2() {

echo  "this is the second
function"

}

[root@wzp ~]# ./7.1test

this is the first function

./7.1test: line 6: fun2: command not found
如上我把fun2放置在定义函数fun2之前就调用,shell是不会回头来执行的,所以对于函数fun2就报错了。

并且还要注意每个函数名必须唯一,如果重新定义函数,那么新定义的将取代原先的定义,看例子:
[root@wzp
~]# cat 7.1test

#!/bin/bash

function fun1 {

echo  "this is the first
function"

}

fun1

fun1() {

echo  "this is the second
function"

}

fun1

[root@wzp ~]# ./7.1test

this is the first function

this is the second function
例子很简单,效果也看出来了,所以我们最好区分出函数名了。

2、返回值

bash
shell将函数看成小型脚本,并以退出状态结束,我们可以通过$?查看三种不同的退出状态,这一点前面已经讲述过了。

2.1、默认退出状态

我们先来看一个例子:

[root@wzp ~]# cat 7.2test

#!/bin/bash

function fun1 {

echo  "this is the first
function"

ls -l xx

}

fun1

echo "the exit status is :$?"

[root@wzp ~]# chmod u+x 7.2test

[root@wzp ~]# ./7.2test

this is the first function
ls: xx: 没有那个文件或目录

the exit status is :2

我们看到函数的退出状态为2,因为最后一条命令执行出错了。再来看看另外一种情况:
[root@wzp
~]# cat 7.2test

#!/bin/bash

function fun1 {

ls -l xx

echo  "this is the first
function"

}

fun1

echo "the exit status is :$?"

[root@wzp ~]# ./7.2test

ls: xx: 没有那个文件或目录

this is the first function

the exit status is :0
我把函数的两条命令调换位置执行,可以看到第一条报错了,然后退出状态值却是0。从这点我们发现函数的默认退出状态是不可靠的。
2.2、使用return命令

return命令可以使用单个整数值来定义函数退出状态,如下例子:
[root@wzp
~]# cat 7.2test

#!/bin/bash

function cto {

read -p "enter a value:" value

echo "doubling the value"

return $[ $value * 2 ]

}

cto

echo "the new value is $?"

[root@wzp ~]# ./7.2test

enter a value:24

doubling the value

the new value is 48
函数cto将变量$value中用户输入的值变成双倍后,使用命令return命令返回结果,然后用$?显示该结果。

2.3、使用函数输出

对于命令输出可以捕获并存放到shell变量中,函数的输出也可以捕获并放到shell变量中,看例子:
[root@wzp
~]# chmod u+x 7.3test

[root@wzp ~]# cat 7.3test

#!/bin/bash

ceo () {

read -p "please input a value:" value

echo $[ $value * 2 ]

}

result=`ceo`  
#注意函数的调用方式
echo "the result is : $result"

[root@wzp ~]# ./7.3test

please input a value:13

the result is : 26
通过定义函数后,把函数输出赋予给变量,这里使用反引号。

3、在函数中使用变量
如下讲述shell脚本函数内外变量处理方法。

3.1、向函数传递参数

bash
shell将函数作为小型脚本处理,函数可以使用标准参数环境变量来表示命令行传递给函数的参数,先看如下例子:

[root@wzp ~]# cat 7.3test

#!/bin/bash

function cio {

if [ $# -eq 0 ] || [ $# -gt 2 ]

then

echo -1

elif [ $# -eq 1 ]

then

echo $[ $1 + $1 ]

else

echo $[ $1 * $2 ]

fi

}

echo "##############1##############"

echo -n "adding 10 and 15 :"

value=`cio 10 15`

echo $value

echo "##############2##############"

echo -n "adding just one num of 10:"

value=`cio 10`

echo $value

echo "##############3##############"

echo -n "adding no num:"

value=`cio`

echo $value

echo "##############4##############"

echo -n "adding three num 10 20 30 :"

value=`cio 10 20 30`

echo $value

[root@wzp ~]# ./7.3test

##############1##############

adding 10 and 15 :150

##############2##############

adding just one num of 10:20

##############3##############

adding no num:-1

##############4##############

adding three num 10 20 30 :-1
先通过$#来判断参数个数,然后针对个数的不同执行不同的算术运算。通过把参数数目传递给函数去运算,把运行结果显示出来。

还有点注意的,因为函数为自己的参数值使用专用的参数环境变量,所以函数无法从脚本命令行直接访问脚本参数值,也就是说函数不识别运行脚本时后面附带的参数值。如果要调用,必须在使用函数时手工传递这些数据,我们来看个例子:
[root@wzp
~]# cat 7.3test

#!/bin/bash

bad () {

echo $[ $1 + $2 ]

}

if [ $# -eq 2 ]

then

value=`bad`

echo "the result is : $value"

else

echo "please input two parameters"

fi

[root@wzp ~]# ./7.3test

please input two parameters

[root@wzp ~]# ./7.3test 1 2

./7.3test: line 3: +  : syntax error: operand
expected (error token is " ")

the result is : 
之所以函数不认识1和2这两个$1、$2,就是因为函数使用的变量不同于脚本主代码的变量,所以我们必须在使用函数的使用手工附加,改成如下:
[root@wzp
~]# cat 7.3test

#!/bin/bash

bad () {

echo $[ $1 + $2 ]

}

if [ $# -eq 2 ]

then

value=`bad $1 $2`

echo "the result is : $value"

else

echo "please input two parameters"

fi

[root@wzp ~]# ./7.3test

please input two parameters

[root@wzp ~]# ./7.3test 8 16

the result is : 24
哈哈,要的就是这个结果,所以value=`bad $1 $2`是关键语句!!!

3.2、在函数中处理变量

这里要提及一个作用域的概念,表示说变量的可见区域。函数内定义的变量和普通变量有不同的作用域,脚本外部定义的变量要覆盖函数内定义的变量。函数使用两个类型的变量:

*全局变量

*局部变量

1》全局变量

全局变量是shell脚本内处处有效的变量,默认情况下脚本中定义的变量都是全局变量,而默认定义的变量在函数内部也可以正常访问的。例子:
[root@wzp
~]# cat 7.3test

#!/bin/bash

fun () {

value=$[ $value * 2 ]

}

read -p "please input the value:"
value

fun

echo "the new value is : $value"

[root@wzp ~]# ./7.3test

please input the value:12

the new value is : 24
对于$value是在函数外部定义的,并且是在外部赋值,当调用给函数fun的时候,该变量在函数中也是有效的,所以这是全局变量的作用体现。

2》局部变量

对于函数内部使用的变量则是局部变量,而在声明变量的时候只要在前面多一个local关键字即可,先看下例子:
[root@wzp
~]# cat 7.3test

#!/bin/bash

function cfo {

local temp=$[ $value + 5 ]

result=$[ $temp + 2 ]

}

temp=8

value=10

cfo

echo "the result is $result"

if [ $temp -gt $value ]

then

echo "temp is larger"

else

echo "temp is smaller"

fi

[root@wzp ~]# ./7.3test

the result is 17

temp is smaller
对于这样的结果,可以分析如下:返回$result的结果是从函数中得到的,那么势必采用函数内部的temp变量,而函数内部的$temp变量赋予值后为15,则显示result的值为15+2=17。这一点没什么好质疑的!但是当temp和result进行大小比较的时候,就直接采用全局变量的值,而跟函数内部定义的temp无关了,这也是local定义内部函数的作用体现了。

这里我们顺便把变量的值取出来看看:
[root@wzp
~]# cat 7.3test

#!/bin/bash

function cfo {

local temp=$[ $value + 5 ]

result=$[ $temp + 2 ]

}

temp=8

value=10

cfo

echo "the result is $result"

if [ $temp -gt $value ]

then

echo "temp is larger"

echo "temp=$temp ; result=$result"

else

echo "temp is smaller"

echo "temp=$temp ; result=$result"

fi

[root@wzp ~]# ./7.3test

the result is 17

temp is smaller

temp=8 ; result=17
我只是多加了两个echo "temp=$temp ;
result=$result",就为了把temp和result这两个变量显示出来,我们看到,执行函数后,temp的值没变,因为函数中局部定义了temp,所以还是8;可是value的值通过函数运算后是有效生成的,所以附加后是17。

4、创建库
函数在单个脚本中有助于减少代码量,如果多个脚本碰巧使用相同的函数可以通过创建函数的库文件,然后再不同脚本中引用该库文件。所以这种方法,首先要创建公共库文件,如下:

[root@wzp ~]# cat funcs

function ceo {

echo $[ $1 + $2 ]

}

function cfo {

echo $[ $1 * $2 ]

}
接下来把如上库文件调用进脚本文件。然后问题在于如果把这个库文件作为普通脚本文件运行,那么这些函数不会出现在脚本文件中,看如下例:
[root@wzp
~]# chmod u+x funcs

[root@wzp ~]# chmod u+x 7.41test

[root@wzp ~]# chmod u+x 7.42test

[root@wzp ~]# cat 7.41test

#!/bin/bash

./funcs

result=`ceo 12 24`

echo "the result is $result"

[root@wzp ~]# ./7.41test

./7.41test: line 3: ceo: command not found

the result is 
可以看到调用库文件失败了,问题就处在于通过./执行库函数是不可行的。

解决办法是通过点符号符在shell脚本中运行库文件脚本,即为source命令,其格式是:

.
./xx  (切记:两个点号之间有个空格,否则出错) 把例子修改如下:
[root@wzp
~]# cat 7.41test

#!/bin/bash

. ./funcs

result=`ceo 12 24`

echo "the result is $result"

[root@wzp ~]# cat 7.42test

#!/bin/bash

.
./funcs    
#这一步相当于添加库
result=`cfo 12 5`

echo "the result is $result"

[root@wzp ~]# ./7.41test

the result is 36

[root@wzp ~]# ./7.42test

the result is 60
我们看到了满意的结果,关键在于通过.
./点符号符来使得脚本能以调用库文件的函数,这里头是把脚本文件和库文件放置于同一目录,所以为了确保路径问题的可靠性可使用绝对路径。

5、在命令行使用函数

有时候想直接在命令行下使用函数也是可以的,在命令行下使用函数有两种方法,分别如下:

1、将函数定义在一行命令中:

[root@wzp ~]# function 51cto { echo $[ $1 / $2 ]; }

[root@wzp ~]# 51cto 100 20

5

上面这种方法必须在命令的结尾处加分号,使得shell知道命令在哪里分开。

2、使用多行命令定义函数:

[root@wzp ~]# function 51ceo {

> echo $[ $1 * $2 ]

> }

[root@wzp ~]# 51ceo 3 8

24
通过次提示符输入更多命令,在函数末尾处使用大括号,shell就知道了定义函数结束,这种方法就不用使用分号了。



bash shell笔记7 创建函数的更多相关文章

  1. bash shell笔记1 脚本基础知识

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/505644 * ...

  2. bash shell笔记2 结构化命令

    二.使用结构化命令 知识内容: # 改变命令流 # 使用if-then逻辑 # 嵌套if-then # 测试条件 # 高级if-then功能 许多程序在脚本命令之间需要某些逻辑控制流,有些命令允许脚本 ...

  3. bash shell笔记6 脚本控制

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/522415 知 ...

  4. bash shell笔记5 显示数据

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/521455 知 ...

  5. bash shell笔记4 处理用…

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/521448 知 ...

  6. bash shell笔记3 结构化命令二

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/513601 三 ...

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

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

  8. shell高级-----创建函数

    基本脚本函数 1.创建函数 有两种格式可以用来在bash shell脚本中创建函数.第一种采用关键字function.后跟分配给该代码的函数名. function name { commands } ...

  9. Shell编程—创建函数

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

随机推荐

  1. PhotoShop脚本指南

    Photoshop脚本语言 Photoshop支持三种脚本语言:AppleScript,VBScript,JavaScript.其中AppleScript为苹果系统,VBScript为Windows操 ...

  2. ng 自定义服务

    服务的本质是对象. 创建服务的常见方式:factory(返回对象) service (方法.属性)constant(常量服务) value(变量服务) 1.factoryapp.factory('服务 ...

  3. Linux命令学习笔记目录

    Linux命令学习笔记目录 最近正在使用,linux,顺便将用到的命令整理了一下. 一. 文件目录操作命令: 0.linux命令学习笔记(0):man 命令 1.linux命令学习笔记(1):ls命令 ...

  4. Django json处理

    转自:http://www.gowhich.com/blog/423 1, 发往浏览器端 前端:jQuery发送GET请求,并解析json数据. url = "http://example. ...

  5. 《DSP using MATLAB》示例Example7.16

    代码: M = 60; alpha = (M-1)/2; l = 0:M-1; wl = (2*pi/M)*l; Hrs = [ones(1, 7), 0.5925, 0.1099, zeros(1, ...

  6. Linq:Grouping Operators

    [Category("Grouping Operators")] [Description("This sample uses group by to partition ...

  7. 常见26个jquery使用技巧详解

    本文列出jquery一些应用小技巧,比如有禁止右键点击.隐藏搜索文本框文 字.在新窗口中打开链接.检测浏览器.预加载图片.页面样式切换.所有列等高.动态控制页面字体大小.获得鼠标指针的X值Y值.验证元 ...

  8. (转)Android 50道面试题总结(大家看看吧)

    1. 方法重载与覆盖的区别?(Overload与Override的区别)2. String 和StringBuffer的区别3. 字符串“abcde”通过写一个函数不让调用第三方的字符串,实现一个字符 ...

  9. spring mvc集成velocity使用

    目前流行的三大页面视图神器是:老牌大哥jsp.后起之秀freemarker和velocity.这里不详细比较这三者的优劣,总体来说,jsp是标配,但后面两个更严格的执行了视图与业务的分离,页面里是不允 ...

  10. 初识C++ 中的STL

    首先,STL是指standard template library,即C++标准模板库,也叫泛型库. STL提供了三种类型的组件:容器,迭代器和算法,他们都支持泛型程序设计标准. (一)容器: 分为: ...