目录
1. 函数基本概述
01. 什么是函数?
函数其实就是一堆命令的合集,用来完成特定功能的代码块,你可以对它进行自定义命令,并且可以在脚本中任意位置使用这个函数,要使用定义的函数,只需要填写函数名称就可以了。
02. 函数的作用
1.使用函数可以让代码模块化,便于代码的复用,同时增加脚本的可读性。
2.函数和变量类似,必须先定义才可使用,如果定义不调用则不会被执行。
2. 函数基本使用
01. 如何定义Shell函数,可以通过如下两种方式进行定义。
方式一
函数名() { command1 command2 ... commandN }
方式二
function 函数名 { command1 command2 ... commandN }
如何调用Shell函数,直接使用函数名调用即可。在函数内部也可以使用$1、$2..$n的方式传递参数。**
#1.命令行定义函数 [root@qiudao /scripts]# fun1() { echo "hello world"; } #2.命令行调用函数 [root@qiudao /scripts]# fun1 hello world #给函数传递参数 [root@qiudao /scripts]# fun2() { echo "hello $1"; } [root@qiudao /scripts]# fun2 linux hello linux #4.给函数传递多个参数{$*,接收所有的参数传递} [root@qiudao /scripts]# fun3() { echo "hello $*"; } [root@qiudao /scripts]# fun3 zhangsan
3. 函数参数传递
如何向函数传递参数,其实函数传参和脚本传参类似,都是使用$1..$9..方式。
01. 函数传参示例,使用变量方式传递固定值
[root@qiudao /scripts]# cat fun-1.sh #!/bin/bash fun_1() { echo "$num" } num=10 #传递参数 fun_1 #调用函数 #执行脚本 [root@qiudao /scripts]# sh fun-1.sh 10
02. 函数传参示例,使用变量方式传递可变的值
[root@qiudao /scripts]# cat fun-2.sh \#!/bin/bash fun_1() { echo "$num" } num=$1 #将脚本的第一个位置参数传递给变量num fun_1 #调用函数 \#执行脚本 [root@qiudao /scripts]# sh fun-2.sh 20 20
03. 函数传参示例,传递多个位置参数
[root@qiudao /scripts]# cat fun-3.sh #!/bin/bash fun_1() { echo "$1" #接收执行函数是传递的第一个参数 } fun_1 $1 #接收脚本第一个位置参数,传入函数中算第一个参数 fun_1 $2 #接收脚本第二个位置参数,传入函数中算第一个参数 fun_1 $3 #接收脚本第三个位置参数,传入函数中算第一个参数 #执行脚本 [root@qiudao /scripts]# sh fun-3.sh 10 20 30 10 20 30 [root@qiudao /scripts]# cat fun-3.sh #!/bin/bash fun_1() { echo "$1" } fun_1 $1 $2 $3 fun_1 $2 fun_1 $3 [root@qiudao shell]# sh fun.sh 1 2 3 1 2 3
04. 函数传参示例,传递多个函数参数
[root@qiudao /scripts]# cat fun-4.sh \#!/bin/bash fun_1() { echo "$1" "$2" "$3" #函数接收传递三个参数 } #rc=$(fun_1 10 20 30) #传递固定的值 rc=$(fun_1 $1 $2 $3) #传递可变的值 echo "传递参数的值为,$rc" #执行脚本 [root@qiudao /scripts]# sh fun-4.sh 10 20 30 传递参数的值为,10 20 30
05. 函数传参示例,将脚本的位置参数与函数的位置参数发生联动。
[root@qiudao /scripts]# cat fun-5.sh #!/bin/bash fun_1() { echo "$num1" "$num2" "$num3" } num1=$1 #将脚本位置参数一的值传递给变量num1 num2=$2 #将脚本位置参数二的值传递变量给num2 num3=$3 #将脚本位置参数二的值传递变量给num3 rc=$(fun_1) #将函数执行的结果保存至rc变量中,便于后续echo输出 echo "传递参数的值为,$rc" #执行脚本 [root@qiudao /scripts]# sh fun-5.sh 10 20 30 传递参数的值为,10 20 30
06. 函数传参使用场景示例,写一个脚本,该脚本可以实现计算器的功能,可以进行加减乘除四种计算
[root@qiudao /opt]# cat fun-6.sh #!/usr/bin/bash cale (){ case $2 in +) echo $1 + $3 = $(( $1 + $3 )) ;; -) echo $1 - $3 = $(( $1 - $3 )) ;; /) echo $1 / $3 = $(( $1 / $3 )) ;; x) echo "$1 x $3 = $(( $1 * $ ))" esac } cale $1 $2 $3
07. 函数传参使用场景示例,需求描述:写一个脚本,实现nginx服务的启动、停止、重启。
[root@backup scripts]# cat stat.sh #!/bin/bash source /etc/init.d/functions if [ $# -ne 1 ];then echo "Usage:$0 {start|stop|reload|status|restart}" exit fi nc=$1 rc() { if [ $? -eq 0 ];then action "nginx is $nc 成功" /bin/true else action "nginx is $nc 失败" /bin/false fi } start() { if [ ! -f /var/run/nginx.pid ];then /usr/sbin/nginx rc else echo "nginx正在运行" fi } stop() { if [ -f /var/run/nginx.pid ];then /usr/sbin/nginx -s stop rc else echo "nginx不在运行" fi } reload () { if [ -f /var/run/nginx.pid ];then /usr/sbin/nginx -s reload rc else echo "nginx不在运行,无法重启" fi } status () { if [ -f /var/run/nginx.pid ];then echo "nginx正在运行" else echo "nginx不在运行,无法重启" fi } case $nc in start) start ;; stop) stop ;; reload) reload ;; restart) nc=stop stop sleep 2 nc=start start ;; status) status ;; *) echo "Usage: $0 {start|stop|reload|status}" exit esac
4. 函数状态返回
Shell的函数返回值,也算是退出的状态。在Shell中只有echo、return两种方式。
1.使用return返回值:只能返回0-255的整数,函数使用return返回值,通常只是用来供其他地方调用获取状态,因此通常仅返回0或1;0表示成功,1表示失败。
2.使用echo返回值:使用echo可以返回任何字符串结果,通常用于返回数据,比如一个字符串值或者列表值。
01. Shell函数echo、return返回值示例
[root@qiudao /scripts]# cat fun_echo_return.sh #!/bin/bash fun_echo_return() { echo 100 #返回函数执行后的数据 return 1 #返回函数执行后的状态码(放置最后) } result=`fun_echo_return` echo "函数的状态码是:$? " echo "函数的返回值是:$result " #执行脚本 [root@qiudao /scripts]# sh fun_echo_return.sh 函数的状态码是:1 函数的返回值是:100
02. Shell函数return返回值使用场景示例
#return示例一: [root@qiudao /scripts]# cat fun_return.sh #!/bin/bash file=/etc/passwd #定义文件 t_file() { if [ -f $file ];then return 0 else return 1 fi } #调用函数,并根据函数返回状态码进行输出 t_file && echo "该文件存在 $file" || echo "该文件不存在 $file" #执行脚本 [root@qiudao /scripts]# sh fun_return.sh 该文件存在 /etc/passwd #return示例二:(了解即可) [root@qiudao /scripts]# cat fun_nginx_run.sh #!/bin/bash this_pid=$$ is_nginx_running() { ps -ef|grep nginx |grep -v grep |grep -v $this_pid &>/dev/null if [ $? -eq 0 ];then return 0 else return 1 fi } #调用函数,并根据函数返回状态码进行输出 is_nginx_running && echo "Nginx is running" || echo "Nginx is stoped"
03. Shell函数返回值场景练习,例:猜数字游戏。
1.如果用户输入的数值大于0且小于10则返回0
2.如果用户输入的数值大于等于10且小于20则返回1
3.如果用户输入的数值大于等于20且小于30则返回2
4.输入其余数值则返回3
[root@qiudao /scripts]# cat fun_return-3.sh \#!/bin/bash checknum() { read -p "请输入对应的数字:" num if [ $num -ge 0 -a $num -le 10 ];then return 0 elif [ $num -gt 10 -a $num -le 20 ];then return 1 elif [ $num -gt 20 -a $num -le 30 ];then return 2 else return 3 fi } #调用函数,函数执行后会通过return返回对应的状态码 checknum rc=$? #根据函数返回值进行判断 if [ $rc -eq 0 ];then echo "你输入的数字是:$num,大于0小于10" elif [ $rc -eq 1 ];then echo "你输入的数字是:$num,大于10小于20" elif [ $rc -eq 2 ];then echo "你输入的数字是:$num,大于20小于30" else echo "你输入的数字是:$num,超出范围!请重新输入" fi
5. 函数场景示例
01. 系统初始化版本
[root@qiudao /scripts]# cat system.sh
#!/bin/bash
#1.显示系统版本
check_system_version() {
awk '{print $(NF-1)}' /etc/redhat-release
}
#2.更新yum源
check_yum() { tt=$(awk '{print $(NF-1)}' /etc/redhat-release) if [ ${tt%%.*} -eq "6" ];then mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/.*repo /etc/yum.repos.d/backup/ curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo elif [ ${tt%%.*} -eq "7" ];then mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/ curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo fi yum clean all && yum makecache }
4.关闭selinux
disable_selinux() { sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config setenforc 0 &> /dev/null }
5.关闭firewalld
disable_firewalld() { systemctl stop firewalld.service systemctl disable firewalld.service }
6.配置sshd服务
ssh_config() { sed -i 's/#UseDNS yes/UseDNS no/g' /etc/ssh/sshd_config sed -i 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/g' /etc/ssh/sshd_config }
7.加大文件描述符
limit_conf() { echo '* - nofile 65535 ' >>/etc/security/limits.conf }
8.时间同步
date_time() { echo '*/5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com &>/dev/null' >/var/spool/cron/root }
menu() { cat <<EOF ########################################## ## 1、操作系统发行版本 ## 2、部署yum源 ## 3、安装系统软件包 ## 4、关闭Selinux ## 5、关闭Firewalld ## 6、配置SSHD服务 ## 7、加大文件描述符 ## 8、同步系统时间 ## 9、打印菜单 ## q、退出程序 ########################################## EOF } #打印菜单 menu while true do read -p "您想干什么?就请输入上面对应的字符:" n case $n in 1) check_system_version ;; 2) check_yum &>/dev/null echo $? &>/dev/null && echo "yum源更新完成" || echo "yum源更新失败" ;; 3) echo "安装软件包需要一部分时间,请耐心等待,正在安装中......." package_install &>/dev/null echo $? &>/dev/null && echo "基础软件包安装完成" || echo "基础软件包安装报错" ;; 4) disable_selinux &>/dev/null echo $? &>/dev/null && echo "Selinux 关闭成功" || echo "Selinux 关闭失败" ;; 5) disable_firewalld &>/dev/null echo $? &>/dev/null && echo "Firewalld 关闭成功" || echo "Firewalld 关闭失败" ;; 6) ssh_config &>/dev/null echo $? &>/dev/null && echo "sshd服务配置完成" || echo "sshd服务配置报错" ;; 7) limit_conf &>/dev/null echo $? &>/dev/null && echo "文件描述符数量修改成功" || echo "文件描述符数量修改失败" ;; 8) date_time &>/dev/null echo $? &>/dev/null && echo "定时任务添加成功" || echo "定时任务添加失败" ;; 9) clear menu ;; q) echo "您即将退出程序!" exit 1 esac done
02. 编写虚拟机管理脚本
安装虚拟机
关闭虚拟机
打开虚拟机
克隆虚拟机
退出程序
03. 编写系统管理工具箱
查看内存的使用情况
查看磁盘的使用情况
查看系统的负载
等等
q键退出程序
[root@qiudao /scripts]# cat case-6.sh #!/bin/bash menu() { cat <<-EOF ############################# ## h 命令帮助 ## d 磁盘使用情况 ## m 内存使用情况 ## v 系统版本 ## k 系统内核版本 ## n 系统静态主机名 ## e eth0网卡ip地址 ## i 外网ip地址 ## u 系统负载情况 ## q 退出程序 ############################# EOF } menu while true do read -p "根据上方的菜单,选择你要查看的信息: " sys case $sys in h) clear menu ;; d) clear df -h ;; m) clear free -m ;; v) clear awk '{print $1,$2,$4}' /etc/redhat-release ;; k) clear uname -r ;; n) clear hostnamectl|grep "Static hostname"|awk '{print $3}' ;; e) clear ifconfig eth0|awk 'NR==2{print $2}' ;; i) clear curl -s icanhazip.com ;; q) clear exit ;; *) clear echo "USAGE: $0 [ h | d | m | v | k | n | e | i | q ]" esac done