Shell脚本——函数(function)

做为一个经常写脚本的运维人员来讲,都能发现一个问题,很多时候我们在不同的脚本里面重复的写着同一段代码。比如我们要去使用正则表达式去判断IP地址的合法性问题,如果每次都去写一遍这个匹配IP的表达式,整个表达式写下来老长老长的,0-9的数字组合看的眼都花了,是不是很累了。当然有人会说了,保存一份正确的代码之后,需要用这段代码的时候,直接粘贴到正在编写的脚本里面不就行了嘛!是没错,但这样是不是很多脚本里面都重复存放着同一段代码,额外增加了脚本的代码量。有没有一个两全其美的办法,让我们的脚本代码量又小,又省去了每次重复的粘贴同一段代码的操作,同时还能完美的调用这段代码了。shell函数的出现为我们完美的解决了这一设想。

函数介绍
 函数(function)是由若干条shell命令组成的语句块,实现代码重用和模块化编程
 它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分

函数和shell程序的区别:
  Shell程序在子Shell中运行
  而Shell函数在当前Shell中运行。因此在当前Shell中,函数可以对shell中变量进行修改

定义函数的语法格式:
函数由两部分组成:函数名和函数体
 语法一:
  function f_name {
  ...函数体...
  }
 语法二:
  function f_name () {
  ...函数体...
  }
 语法三:
  f_name (){
  ...函数体...
  }

函数的定义方式:
 1,可在交互式环境下直接定义函数,当前shell环境可调用
 2,可将函数定义在脚本文件中作为它的一部分,只可自己调用
 3,可写成单独的函数库文件中,任何脚本都可以调用

函数的撤销方式:unset 函数名

函数的调用方式:
 1,调用函数库中的函数时,首先得用source或.载入函数库文件,再指定要调用的函数名
   注意:<点> <空格> <函数库文件名>文件名要带正确路径
 2,命令行定义的、脚本自身定义的,直接指定要调用的函数名即可

函数名出现的地方,会被自动替换为函数代码
 函数的生命周期:被调用时创建,返回时终止

修改已定义的函数:
 1,使用set命令查看所有定义的函数,其输出列表包括已经载入shell的所有函数
 2,用unset命令从shell中删除函数;改动完毕后,再重新载入此函数或函数库文件

函数返回值
函数有两种返回值:
 1,函数的执行结果返回值:
  (1) 使用echo或printf命令进行输出
  (2) 函数体中调用命令的输出结果

2,函数的退出状态码:
  (1) return:默认取决于函数中执行的最后一条命令的退出状态码
  (2) return #:自定义退出状态码,其格式为:
   return 0  无错误返回
   return 1-255  有错误返回

交互式环境下定义和使用函数

示例代码:
 dir() {
 > ls -l
 > }
 定义该函数后,若在命令行键入dir,其显示结果同ls -l的作用
 该dir函数将一直保留到用户从系统退出,或执行了unset命令:unset dir

在脚本中定义及使用函数
 函数在使用前必须定义,因此应将函数定义放在脚本开始部分,直至shell首次发现它后才能使用
 调用函数仅使用其函数名即可

示例代码:
#!/bin/bash

maxnum () {
if [[ $1 -gt $2 ]];then
  max=$1
  min=$2
elif [[ $1 -lt $2 ]];then
  min=$1
  max=$2
fi
echo maxnum is : $max
echo minnum is : $min
}

maxnum 100 200

建立函数库存文件
示例代码:
#!/bin/bash

#Author:wangjun
#Contact QQ:183530300
#Version:1.0
#Create time:2016-08-18 14:58:52
#Description:founction lib

#maxnum and minnum
maxnum () {
if [[ $1 -gt $2 ]];then
  max=$1
  min=$2
elif [[ $1 -lt $2 ]];then
  min=$1
  max=$2
fi
echo maxnum :$max
echo minnum :$min
}

#operation
operation () {
let sum=$[$1+$2]
echo "$1 $2 sum is : $sum"
let reduce=$[$1-$2]
echo "$1 $2 reduce is : $reduce"
let product=$[$1*$2]
echo "$1 $2 product is : $product"
let quotient=$[$1/$2]
echo "$1 $2 quotient is : $quotient"
}

函数参数(函数可以接受参数):
传递参数给函数:调用函数时,在函数名后面以空白分隔给定参数列表即可;例如“testfunc arg1 arg2 ...”
在函数体中当中,可使用 $1,$2,...这些位置变量;还可以使用 [email protected],$*,$# 等特殊变量

函数变量
变量作用域:
环境变量:当前shell和子shell有效
本地变量:只在当前shell进程有效,执行脚本时会启动专用子shell进程;因此,本地变量的作用范围是当前shell脚本,包括脚本中的函数
局部变量:函数的生命周期内有效;函数结束时变量被自动失效
 注意:如果函数中有局部变量,其名称同本地变量,局部变量会覆盖本地变量

          在函数中定义局部变量的方法:local NAME=VALUE

函数递归:函数直接或间接调用自身

递归实例:
 阶乘是基斯顿·卡曼于1808年发明的运算符号,是数学术语一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且有0的阶乘为1,自然数n的阶乘写作n!
  n!=1×2×3×...×n
 阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n。
  n!=n(n-1)(n-2)...1
  n(n-1)! = n(n-1)(n-2)!

定义标准递归函数:
示例代码:
recursive () {
if [ $1 -eq 0 -o $1 -eq 1 ];then
  echo 1
else
  echo $[$1*$(recursive $[$1-1])]
fi
}

注意递归层数:shell环境下递归最大支持25,超过25的递归shell就无法计算并表示出来了

脚本中调用函数应用实例:

用户管理需要调用的函数库文件

[[email protected] fun]# cat function
#!/bin/bash

#Author:wangjun
#Contact QQ:183530300
#Version:1.0
#Create time:2016-08-18 14:58:52
#Description:founction lib

adduser () {
read -p "Please input a new username : " user
! id $user &> /dev/null && useradd $user &> /dev/null && echo "$user user add success" || echo "$user user exists"
}

deluser () {
read -p "Please input a exists username : " user
id $user &> /dev/null && userdel -r $user &> /dev/null && echo "$user user delet success" || echo "$user user doesn‘t exist"
}

addgroup () {
read -p "Please input a new groupname : " group
! (getent group | grep "^$group\>") &> /dev/null && groupadd $group &> /dev/null && echo "$group group add success" || echo "$group group exists"
}

delgroup () {
read -p "Please input a exists groupname : " group
getent group | grep "^$group\>" &> /dev/null && groupdel $group &> /dev/null && echo "$group group delet success" || echo "$group group doesn‘t exist"
}

调用函数库实现用户管理的脚本
[[email protected] fun]# cat useradmin.sh
#!/bin/bash

#Author:wangjun
#Contact QQ:183530300
#Version:1.0
#Create time:2016-08-18 19:29:03
#Description:User admin function test

. function
PS3="Please choice : "
select choose in "add user" "delet user" "add group" "delet group" "exit"
do
  case $choose in
  "add user")
  adduser
  ;;
  "delet user")
  deluser
  ;;
  "add group")
  addgroup
  ;;
  "delet group")
  delgroup
  ;;
  exit)
  exit
  ;;
  esac
done
[[email protected] fun]#

执行效果如图所示:

通过这个实例,我们不难发现,调用函数写出来的脚本代码量又小,看起来相当清析,提前定义好的函数集中存放至自己的函数库中,日后调用起来是不是也非常省事了。关于函数就先分享到这儿,简单的应用应该没问题了。当然后续会随时更新。

时间: 2024-10-18 00:36:01

Shell脚本——函数(function)的相关文章

Shell脚本-----函数

语法格式 函数名称() { 函数体 } 函数名称 -------------------------- 函数体可包含命令 循环 判断 例子:判断用户是否存在,存在输出用户ID和Shell #!/bin/bash username() {        read -p "please username: " username        if id $username &> /dev/null;then                name=$(grep "^

Linux命令参数处理 shell脚本函数getopts

getopts 命令 用途 处理命令行参数,并校验有效选项. 语法 getopts 选项字符串 名称 [ 参数 ...] 描述 getopts 的设计目标是在循环中运行,每次执行循环,getopts 就检查下一个命令行参数,并判断它是否合法.即检查参数是否以 - 开头,后面跟一个包含在 options 中的字母.如果是,就把匹配的选项字母存在指定的变量 variable 中,并返回退出状态0:如果 - 后面的字母没有包含在 options 中,就在 variable 中存入一个 ?,并返回退出状

利用shell脚本函数实现网络连通性的检测

通常情况下,linux系统网络连通性的检测有两种方法: 1.通过“ping指令 + 目标IP” 或者 “ping指令 + 目标IP域名” 注意针对IPv6地址的IP网络检测需要试用ping6,同时ping6中不能使用参数hops,因为IP6源码中已经舍弃了路由,见如下英文解释: SYNOPSIS       ping  [-aAbBdDfhLnOqrRUvV] [-c count] [-F flowlabel] [-i interval] [-I interface] [-l preload]

shell脚本函数判断输入的IP地址是否符合规则

#判断IP是否符合标准规则 function judge_ip(){         #这里local $1出错,用2>/dev/null屏蔽掉错误,暂未发现影响输出结果         local $1 2>/dev/null         TMP_TXT=/tmp/iptmp.txt         echo $1 > ${TMP_TXT}         IPADDR=`grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' ${TMP_TXT}`     

关于shell脚本函数、数组、字符串截取、svn更新发布实例

#/bin/bash #功能:QA服根据模板创建区配置文件并提交到svn上. SOURCE_PATH=/data/source_code SVN_PATH=/code/psm   #svn发布目录,要先推送到这个目录,然后更新提交 dir="/data/source_code/configfiles" default_conf="config.properties" default_socket_conf="socket.lp" LOG_FILE

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

可以将shell脚本代码放进函数中封装起来,这样就能在脚本中的任何地方多次使用它了. 17.1 基本的脚本函数 函数:是一个脚本代码块,可以为其命名并在代码中任何位置重用. 17.1.1 创建函数 有两种格式:name 是函数名 1) function name {          commands } 2)这种就比较接近c语言风格了 name() {          commands } 17.1.2 使用函数 跟其他shell命令一样,在行中指定函数名就好了. 在函数定义前使用函数,会收

shell脚本中的循环

常用到的循环有for循环和while循环. for循环 [[email protected] sbin]# cat for.sh #! /bin/bash for i in `seq 1 5`; do echo $i done 脚本中的 seq 1 5 表示从1到5的一个序列.你可以直接运行这个命令试下.脚本执行结果为: [[email protected] sbin]# sh for.sh 1 2 3 4 5 通过这个脚本就可以看到for循环的基本结构: for 变量名 in 循环的条件: d

Day01 Shell脚本编程

一.shell环境及特性 1.1 什么是shell 解释器:负责向内核翻译及传达用户/程序指令解释器 车shell 汽车bash 宝马.奔驰.法拉利 1.1.1 /etc/shells 文件里面的内容就是系统已安装的解释器 1.1.2 usermod -s /bin/tsh zhangsan 修改老用户的默认解释器 1.1.3 useradd -s /bin/tsh zhangsan 创建新用户时指定默认解释器 1.2 Bash基本特性 1.2.1 快捷键 ctrl+l清屏ctrl+c终止当前运

复习shell脚本

什么是shell脚本.首先它是一个脚本,并不能作为正式的编程语言.因为是跑在linux的shell中,所以叫shell脚本.说白了,shell脚本就是一些命令的集合.举个例子,我想实现这样的操作: 1)进入到/tmp/目录: 2)列出当前目录中所有的文件名: 3)把所有当前的文件拷贝到/root/目录下: 4)删除当前目录下所有的文件. 简单的4步在shell窗口中需要你敲4次命令,按4次回车.这样是不是很麻烦?当然这4步操作非常简单,如果是更加复杂的命令设置需要几十次操作呢?那样的话一次一次敲