Linux Shell之七 函数应用

简介:

函数是什么?

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

    一旦函数定义好了,执行这个名称,就好象执行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个

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
declare  -i i=0
set  10 20 30 40 50
  for  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这个变量中。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[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



本文转自Jacken_yang 51CTO博客,原文链接:http://blog.51cto.com/linuxnote/1641215,如需转载请自行联系原作者

相关文章
|
3月前
|
存储 安全 Unix
七、Linux Shell 与脚本基础
别再一遍遍地敲重复的命令了,把它们写进Shell脚本,就能一键搞定。脚本本质上就是个存着一堆命令的文本文件,但要让它“活”起来,有几个关键点:文件开头最好用#!/usr/bin/env bash来指定解释器,并用chmod +x给它执行权限。执行时也有讲究:./script.sh是在一个新“房间”(子Shell)里跑,不影响你;而source script.sh是在当前“房间”里跑,适合用来加载环境变量和配置文件。
|
3月前
|
算法 Linux Shell
Linux实用技能:打包压缩、热键、Shell与权限管理
本文详解Linux打包压缩技巧、常用命令与原理,涵盖.zip与.tgz格式操作、跨系统传文件方法、Shell运行机制及权限管理,助你高效使用Linux系统。
Linux实用技能:打包压缩、热键、Shell与权限管理
|
3月前
|
存储 Shell Linux
八、Linux Shell 脚本:变量与字符串
Shell脚本里的变量就像一个个贴着标签的“箱子”。装东西(赋值)时,=两边千万不能有空格。用单引号''装进去的东西会原封不动,用双引号""则会让里面的$变量先“变身”再装箱。默认箱子只能在当前“房间”(Shell进程)用,想让隔壁房间(子进程)也能看到,就得给箱子盖个export的“出口”戳。此外,Shell还自带了$?(上条命令的成绩单)和$1(别人递进来的第一个包裹)等许多特殊箱子,非常有用。
|
5月前
|
安全 应用服务中间件 网络安全
在Linux环境部署Flask应用并启用SSL/TLS安全协议
至此,你的Flask应用应该能够通过安全的HTTPS协议提供服务了。记得定期更新SSL证书,Certbot可以帮你自动更新证书。可以设定cronjob以实现这一点。
335 10
|
5月前
|
Web App开发 缓存 安全
Linux一键清理系统垃圾:释放30GB空间的Shell脚本实战​
这篇博客介绍了一个实用的Linux系统盘清理脚本,主要功能包括: 安全权限检查和旧内核清理,保留当前使用内核 7天以上日志文件清理和系统日志压缩 浏览器缓存(Chrome/Firefox)、APT缓存、临时文件清理 智能清理Snap旧版本和Docker无用数据 提供磁盘空间使用前后对比和大文件查找功能 脚本采用交互式设计确保安全性,适合定期维护开发环境、服务器和个人电脑。文章详细解析了脚本的关键功能代码,并给出了使用建议。完整脚本已开源,用户可根据需求自定义调整清理策略。
570 0
|
5月前
|
Java Linux 网络安全
Linux云端服务器上部署Spring Boot应用的教程。
此流程涉及Linux命令行操作、系统服务管理及网络安全知识,需要管理员权限以进行配置和服务管理。务必在一个测试环境中验证所有步骤,确保一切配置正确无误后,再将应用部署到生产环境中。也可以使用如Ansible、Chef等配置管理工具来自动化部署过程,提升效率和可靠性。
533 13
|
4月前
|
存储 数据采集 监控
ubuntu(linux)系统主要应用于哪些工业场景中?研维三防ubuntu系统的手持工业三防平板电脑在哪些行业中有实际应用
Ubuntu 系统凭借其独特的优势,在众多工业场景中得到了广泛应用,为工业数字化、智能化发展提供了有力支持。而研维三防基于 Ubuntu 定制系统的手持工业三防平板电脑,更是将 Ubuntu 系统的优势与工业级的性能、坚固耐用性完美结合,在电力、物流、制造等多个行业中展现出强大的应用价值,助力企业提高生产效率、优化管理流程、提升产品质量,成为推动工业现代化发展的重要力量。随着技术的不断进步与创新,相信 Ubuntu 系统以及研维三防这类工业级设备将在更多的工业领域中发挥更大的作用,为工业发展带来更多的机遇与变革。
|
7月前
|
Linux Shell
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
200 4
|
7月前
|
Linux Shell 数据安全/隐私保护
Centos或Linux编写一键式Shell脚本创建用户、组、目录分配权限指导手册
Centos或Linux编写一键式Shell脚本创建用户、组、目录分配权限指导手册
407 3
|
8月前
|
Linux Shell
shell_42:Linux参数移动
总的来说,参数移动是Linux shell脚本中的一个重要概念,掌握它可以帮助我们更好地处理和管理脚本中的参数。希望这个解释能帮助你理解和使用参数移动。
173 18