函数是什么?

函数是一些命令的集合,使用一个名称做代表,称为函数名称。函数名称的命名规则和变量相同。

一旦函数定义好了,执行这个名称,就好象执行Bash的命令一样,称为调用函数。实际上,Bash调用函数时,会执行函数里的命令区域,执行

完毕,Bash会回到调用函数的下一行继续执行。

函数的最大作用是可以让程序模块化。如果Script程序中,需要重复执行某一命令区域,那么就应当使用函数代表这个区域,一方面可使程序精简,一方面程序代码页比较容易维护。

一、函数的用法

1、函数的语法

语法1:

function 函数名称()

{

命令区域

}

函数名称与()之间可以直接相连,也可用空格隔开。

语法2:

函数名称()

{

命令区域

}

关键词function可省略

语法3:

function 函数名称

{

命令区域

}

如果使用关键词function,函数名称后的()也可省略

例子:

#!/bin/bash

getline ()          #定义函数getline,用来定义文件行数

{

local i=0          #i代表已计算的行数,先归0。

#local用来设定变量i是getline函数中专有的变量,不影响script其它地方也叫i的函数

while read line

do                 #使用while循环,自变量值$file指定文件读取每一行

let ++i           #每读一行 变量i值+1

done < $file       #使用转向输入,让read能由$file读取数据

echo "$file文件共有$i行"   #显示总行

}

file=$1             #由命令行第一个参数,取得要计算行数的文件名。

getline            #调用getline函数

echo "getline 执行完毕"   #getline执行完后,回到这里继续执行下一指令。

#./script passwd

passwd文件共有36行

getline执行完毕

在调用函数之前一定要先定义该函数。

unset -f 函数  取消函数

2、函数的结束状态

执行函数时,函数中最后一个命令的传回值代表函数的结束状态。执行函数如果遇到return命令,就立即结束,回到调用函数的下一个命令,此时函数的传回值为0

#!/bin/bash

getline ()

{

local i=0

while read line

do

let ++i

if (($i > 10));then        #判断是否超过10行

echo "$file文件大于10行,不再继续"

return                   #遇到return命令,立即回到echo$?所在行

#默认传回值为0,也可指定不同的传回值,直接在return空格加数字即可

fi

done < $file

echo "$file文件共有$i行"

}

file=$1

getline

echo $?

echo "getline 执行完毕"

可以根据$?(return 接的数字n )的值执行想要的命令,如上  if[ $? -eq 3 ];then

echo "行数过多,放弃读取"

else

echo 'getline执行完毕'

fi

二、函数与变量的作用范围。

1、函数的作用范围

函数仅在定义的shell环境中有效,Bash执行函数时,并不会另外再开启一个子shell。

如果要传递函数给shell环境使用,可以用内置命令export   -f函数名称,这样此函数就变成了环境变量的一部分(函数型),可供子shell的script调用。

2、变量的作用范围

如果没有特别的设定变量的属性,那么在Script中自定义的变量称为全局变量(对此脚本而言)。作用范围在整个Script文件中皆有效。

#!/bin/bash

getline ()

{

local i=0               #这就定义了变量i只在函数getline中有效,变量i和函数外其它叫i的变量完全不一样。

while read line

do

....

三、位置参数

1、命令行的位置参数

$0  表示脚本名 $1 表示第一个参数 $2表示第2给参数 $(10)表示第10个参数

$*    代表所有的位置参数,看为一个字符串。1.sh a x y则$*为"a x y"

$@    代表所有以空白隔开的参数,各位置串行。    1.ah a x y则$@为"a"、"x"、"y"

$#    位置参数的个数,1.ah a x y则$#的值为3

#!/bin/bash

if [ $# -ne 2 ];then                必须键入2个参数,否则错误退出

echo "使用方法:./$0 参数1 参数2"

exit 1

fi

2、移动位置参数

Bash的内置命令shift可以往前移动位置参数的值,语法如下:

shift n

n为正整数,代表往前移动的次数。n可以省略不写代表移动一次。执行 shift n,$(n+1)的值会放入$1

以执行shift命令来说(不指定次数),$2的值放入$1,$3的值放入$2,$4的值放入$3,,,如果一直执行shift(次数>=n),会把所有的位置参数清空

shift 一次清除1个(从$1开始) ,shift 2 一次清除2个#!/bin/bash

echo "\$@的初始值为$@"

while shift

do

[ -n "$1" ] && echo "shift 1次,\$@的变化:$@"

done

执行结果:

[root@centos tmp]# bash 1.sh  a b c d e

$@的初始值为a b c d e

shift 1次,$@的变化:b c d e

shift 1次,$@的变化:c d e

shift 1次,$@的变化:d e

shift 1次,$@的变化:e

3、指定位置参数的值

指定位置参数的值称为重置(reset),用Bash命令set#!/bin/bash

declare -i i=0

set 10 20 30 40 50

for p in $@

do

((i++))

echo " 第 $i 个位置参数 $$i = $p"     #$$目前bash shell的进程编号

done

[root@centos tmp]# bash 2.sh

第 1 个位置参数 3547i = 10

第 2 个位置参数 3547i = 20

第 3 个位置参数 3547i = 30

第 4 个位置参数 3547i = 40

第 5 个位置参数 3547i = 50

一旦用set重置位置参数,其原有的值就会消失,改以新值取代。(无论输入几个参数,set设置几个就是几个)

如果要一次重置所有参数,使其值为空,可执行 set --

4、取用命令行的选项和参数

在设计脚本的时候,往往需要由命令行中取得用户提供的选项和参数,根据不同的选项,脚本有不同的处理方式和执行结果。选项的使用方式可以

是单一选项,也可以在选项后方加上准备作用的参数,而且,选项出现的次序并没有严格的要求。

如以下例子:

./script -u jacken -a -h

或改用以下形式

./script -a -u jacken -h

如果要想取得这些选项和参数,使用前述的位置参数也是可以的,不过拿到位置参数后,必须再做许多条件判断才行,因为选项可能以不同的次序

出现在命令行不同的位置,情况十分复杂。解决这样的问题,可改用Bash提供的内置命令getopts。

getopts语法如下:

getopts 选项行 选项变量

其中选项行,是由各选项的单一字符组成,如前述例子中用来3个选项,可组合成“u:ah”

如果某一个选项字符后方,接上":" 则表示该选项需要提供一个参数,如这里的u后面有":"

如果执行脚本的时候,选项u后方没有提供额外的参数,那么Bash就会显示“option requires an argument --u”的错误信息。

如果不想出现这种错误信息,可在选项行最前面加上":" 如 ":u:ah" 像这样子,u后边没有参数也不会报错了。

至于选项变量的作用是:

getopts由命令行取得选项,把它放入选项变量中,如果该选项需要额外的参数,参数值会放入OPTARG这个变量中。

例子:[root@Shell ~]# ./opt.sh -a

提供了选项a

[root@Shell ~]# ./opt.sh -h

提供了选项h

[root@Shell ~]# ./opt.sh -a -h

提供了选项a

提供了选项h

[root@Shell ~]# ./opt.sh -u

./opt.sh: option requires an argument -- u

[root@Shell ~]# ./opt.sh -u hello

提供了选项-u和参数:hello

[root@Shell ~]# cat opt.sh

#!/bin/bash

#

while getopts u:ah opt

do

case $opt in

u)

echo "提供了选项-u和参数:$OPTARG";;

a)

echo "提供了选项a";;

h)

echo "提供了选项h";;

*)

;;

esac

done

[root@Shell ~]#

四、建立函数库

如果某些函数经常出现在设计的script中,可以考虑把这些函数抽出来,集中存成一个文件,但这个文件称为函数库。

在命名函数时,函数名称第一个字符使用_(下划线),通常这就代表系统用的函数或变量名称。

在/tmp下建立函数库mylib1.sh

_getip()

{

local tmp r ip                           #函数内部使用的变量设为私有

[ -z "$1" ] && return                     #如果位置参数$1为空,直接退出

shuzu=()                                   #建立数组变量shuzu,作为传回ip字符串用,初始值设为空数组

tmp=$(ifconfig $1 | grep 'inet addr')

r=${tmp/inet addr:/}

ip=${r/Bcast*/}

shuzu=($ip)                                #将找到的ip设为第一个数组元素,作为函数处理结果的传回值

}

调用函数数据库的语法,. /路径/函数数据库   .也用source来表示

#!/bin/bash

MYLIB_DIR="/tmp"                           #设置函数库默认路径

if [ ! -d "MYLIB_DIR" ];then

MYLIB_DIR="."                           #如果默认路径不存在就设为当前目录

fi

. $MYLIB_DIR/mylib1.sh                     #调用函数库mylib1.sh

_getip eth0                                #执行_getip传入的参数是网络接口的名称eth0

ip=${shuzu[0]}                             #取出代表函数执行结果的数组变量shuzu的第一个元素,设值给变量ip

if [ -n "$ip" ];then                       #判断$ip是否为空,-z 为空 -n不为空

echo "主机ip是:$ip"

else

echo "找不到IP"

fi

linux 信号传递函数,Linux Shell之七 函数应用相关推荐

  1. linux信号子系统,Linux时间子系统之(三):用户空间接口函数

    Linux时间子系统之(三):用户空间接口函数 作者:linuxer 发布于:2014-12-24 15:48 分类:时间子系统 一.前言 从应用程序的角度看,内核需要提供的和时间相关的服务有三种: ...

  2. linux信号使用,linux信号使用注意事项

    1.不要在信号处理函数中处理复杂的事情 2.信号处理函数中不能有互斥锁会造成死锁,可以用信号量替代 3.信号是置位方式实现,多次发送相同的信号可能只会收到一次 4.子进程具有继承父类信号屏蔽,不能在信 ...

  3. linux信号11sigtstp,Linux信号(signal)机制

    信号(signal)是一种软中断,信号机制是进程间通信的一种方式,采用异步通信方式 一.信号类型 Linux系统共定义了64种信号,分为两大类:可靠信号与不可靠信号,前32种信号为不可靠信号,后32种 ...

  4. adb shell 修改文件名_从零开始学Linux运维|27.Shell编程(函数与参数的传递)

    1.函数 shell可以定义函数,方便调用,定义函数的格式 中括号"[]"内的内容可以省略 [ function ] 函数名 [()]{执行语句;[return 返回值;]} 写一 ...

  5. linux 信号优先级,linux内核中的信号机制

    linux内核中的信号机制--信号处理 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csdn.net ...

  6. linux信号管道,linux编程及应用任继平08 进程间通信-管道和信号.pptx

    linux编程及应用任继平08 进程间通信-管道和信号 管道示例 牛牛文库文档分享创建无名管道 牛牛文库文档分享文件描述符重定向 (1)cattest02test02 2>error test0 ...

  7. linux命令和Linux基本常用的知识详解

    Linux简介与厂商版本 1. Linux简介 Linux可以有狭义和广义两种定义.狭义来说,Linux实际上指Linux kernel (内核).内核负责管理硬件,并为上层应用提供接口.而广义来说, ...

  8. linux 信号 core,Shell 信号发送与捕捉

    原标题:Shell 信号发送与捕捉 作者:李振良OK 1.Linux信号类型 信号(Signal):信号是在软件层次上对中断机制的一种模拟,通过给一个进程发送信号,执行相应的处理函数. 进程可以通过三 ...

  9. 《linux命令行与shell脚本编程大全》第三版 - 核心笔记(3/4):函数与图形化脚本

    <linux命令行与shell脚本编程大全> 全书4部分: ☆ [1]linux命令行(1-10章) ☆ [2]shell脚本编程基础(11-16章) ☆ [3]高级shell脚本编程(1 ...

最新文章

  1. Win8兼容ARM十大意义:打破垄断拉低价格
  2. Postgresql在Windows下的解压安装
  3. python长度分割文本_python 按照固定长度分割字符串的方法小结
  4. Web应用验证码方面总结(ASP.NET版)
  5. java中判断字符串乱码_java中如何判断字符串是否乱码
  6. CIO实施精细化管理的五个要点
  7. vs 窗体连接mysql_vs2008 c#开发windows窗体程序,怎么连接数据库?
  8. Mac/Linux/Centos终端中上传文件到Linux云服务器
  9. 『线性同余方程和中国剩余定理』
  10. mysql生产应用_MySQL备份利器之Xtrabackup--生产应用
  11. 这可能是迄今为止对大前端最好的解释
  12. WolframTones:用一种新科学谱写一种新音乐
  13. Mac苹果安装Win7时鼠标和键盘没有响应
  14. php调用声卡,图文讲解美国ART USB Dual Pre声卡多种使用方法!
  15. 美股,期货和国债随着大选进行中持续大幅度波动,华尔街如何看待这次结局?
  16. Mybatis-入门程序(二)
  17. C语言程序——用星号打印图案
  18. 大数据就业方向_如今大数据行业就业前景如何?
  19. 一筐鸡蛋编程解题Java_一筐鸡蛋总共369个标准答案怎么算的?求法解答公式解题步骤...
  20. 日月光华深度学习(五)--卫星图像识别tf.data、卷积综合实例

热门文章

  1. .NET C#语言基础 20140814
  2. Oracle Golden Gate 系列十七 -- GG 一对多 real-time data distribution 说明 与 示例
  3. 深入浅出 Javascript API(五)--Query Find 查询
  4. 维秘天使超模美女Romee Strijd性感运动照片
  5. 2019年陕西省普通高校招生考生成绩统计表(理工、艺理、体育)
  6. 人工智能,机器学习,深度学习入门好文,强烈推荐
  7. 线性求逆元模板_ACM 数论基本模板
  8. python开发环境spyder_spyder python 2.7-spyder(Python开发环境)下载 v2.1.10官方版--pc6下载站...
  9. 理解线程池中线程的复用原理
  10. 010_jQuery获取和设置内容属性