SHELL编程之函数的定义及调用

原文链接:

SHELL编程之函数的定义及调用

在这里插入图片描述

函数

1. 什么是函数?

  • shell中允许将一组命令集合语句形成一段可用代码,这些代码块称为shell函数
  • 给这段代码起个名字称为函数名,后续可以直接调用该段代码的功能

2. 如何定义函数?

方法1:

函数名()
{
  函数体(一堆命令的集合,来实现某个功能)   
}

方法2:

function 函数名()
{
   函数体(一堆命令的集合,来实现某个功能)
   echo hello
   echo world
}

函数中return说明:

  1. return可以结束一个函数。类似于循环控制语句break(结束当前循环,执行循环体后面的代码)。
  2. return默认返回函数中最后一个命令状态值,也可以给定参数值,范围是0-256之间。
  3. 如果没有return命令,函数将返回最后一个指令的退出状态值。

3. 函数如何调用?

(一) 当前命令行调用

[root@localhost tmp]# cat fun1.sh 
#!/bin/env bash

hello(){
echo "hello future $1"
hostname
}

menu(){
cat <<-EOF
1. mysql
2. web
3. app
4. exit
EOF
}

[root@localhost tmp]# vim fun1.sh
[root@localhost tmp]# source fun1.sh 
[root@localhost tmp]# . fun1.sh 
[root@localhost tmp]# hello 5201314
hello future 5201314
localhost.localdomain
[root@localhost tmp]# menu
1. mysql
2. web
3. app
4. exit

(二)定义到用户的环境变量中

[root@localhost tmp]# vim ~/.bashrc
You have new mail in /var/spool/mail/root
[root@localhost tmp]# cat ~/.bashrc
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi
hello(){
echo "hello future $1"
hostname
}

menu(){
cat <<-EOF
1. mysql
2. web
3. app
4. exit
EOF
}

注意:
当用户打开bash的时候会读取该文件

(三) 脚本中调用

#!/bin/bash
#打印菜单
source ./fun1.sh
menu(){
cat <<-END
	h	显示命令帮助
	f	显示磁盘分区
	d	显示磁盘挂载
	m	查看内存使用
	u	查看系统负载
	q	退出程序
	END
}
menu		//调用函数

4. 应用案例

具体需求:

  1. 写一个脚本收集用户输入的基本信息(姓名,性别,年龄),如不输入一直提示输入
  2. 最后根据用户的信息输出相对应的内容

思路:

  1. 交互式定义多个变量来保存用户信息 姓名、性别、年龄

  2. 如果不输一直提示输入

    • 循环直到输入字符串不为空 while 判断输入字符串是否为空
    • 每个信息都必须不能为空,该功能可以定义为一个函数,方便下面脚本调用
  3. 根据用户输入信息做出匹配判断

代码实现:

#!/bin/bash
#该函数实现用户如果不输入内容则一直循环直到用户输入为止,并且将用户输入的内容打印出来
input_fun()
{
  input_var=""
  output_var=$1
  while [ -z $input_var ]
	do
	read -p "$output_var" input_var
	done
	echo $input_var
}

input_fun 请输入你的姓名:

或者
#!/bin/bash
fun()
{
	read -p "$1" var
	if [ -z $var ];then
		fun $1
	else
		echo $var
	fi
}


#调用函数并且获取用户的姓名、性别、年龄分别赋值给name、sex、age变量
name=$(input_fun 请输入你的姓名:)
sex=$(input_fun 请输入你的性别:)
age=$(input_fun 请输入你的年龄:)

#根据用户输入的性别进行匹配判断
case $sex in
			man)
			if [ $age -gt 18 -a $age -le 35 ];then
				echo "中年大叔你油腻了吗?加油"
			elif [ $age -gt 35 ];then
				echo "保温杯里泡枸杞"
			else
				echo "年轻有为。。。"
			fi
			;;
			woman)
			xxx
			;;
			*)
			xxx
			;;
esac

扩展延伸:

描述以下代码含义:	
:()
{
   :|:&
}
:

综合案例

1. 任务背景

现有的跳板机虽然实现了统一入口来访问生产服务器,yunwei用户权限太大可以操作跳板机上的所有目录文件,存在数据被误删的安全隐患,所以希望你做一些安全策略来保证跳板机的正常使用。

2. 具体要求

  1. 只允许yunwei用户通过跳板机远程连接后台的应用服务器做一些维护操作
  2. 公司运维人员远程通过yunwei用户连接跳板机时,跳出以下菜单供选择:
欢迎使用Jumper-server,请选择你要操作的主机:
1. DB1-Master
2. DB2-Slave
3. Web1
4. Web2
h. help
q. exit
  1. 当用户选择相应主机后,直接免密码登录成功
  2. 如果用户不输入一直提示用户输入,直到用户选择退出

3. 综合分析

  1. 将脚本放到yunwei用户家目录里的.bashrc文件里(/shell05/jumper-server.sh)
  2. 将菜单定义为一个函数[打印菜单],方便后面调用
  3. 用case语句来实现用户的选择【交互式定义变量】
  4. 当用户选择了某一台服务器后,进一步询问用户需要做的事情 case…esac 交互式定义变量
  5. 使用循环来实现用户不选择一直让其选择
  6. 限制用户退出后直接关闭终端 exit

4. 实现

#!/bin/bash
# jumper-server
# 定义菜单打印功能的函数
menu()
{
cat <<-EOF
欢迎使用Jumper-server,请选择你要操作的主机:
1. DB1-Master
2. DB2-Slave
3. Web1
4. Web2
h. help
q. exit
EOF
}
# 屏蔽以下信号
trap '' 1 2 3 19
# 调用函数来打印菜单
menu
#循环等待用户选择
while true
do
# 菜单选择,case...esac语句
read -p "请选择你要访问的主机:" host
case $host in
	1)
	ssh root@10.1.1.1
	
	2)
	ssh root@10.1.1.2
	;;
	3)
	ssh root@10.1.1.3
	;;
	h)
	clear;menu
	;;
	q)
	exit
	;;
esac
done


将脚本放到yunwei用户家目录里的.bashrc里执行:
bash ~/jumper-server.sh
exit

进一步完善需求

为了进一步增强跳板机的安全性,工作人员通过跳板机访问生产环境,但是不能在跳板机上停留。

#!/bin/bash
#公钥推送成功
trap '' 1 2 3 19
#打印菜单用户选择
menu(){
cat <<-EOF
欢迎使用Jumper-server,请选择你要操作的主机:
1. DB1-Master
2. DB2-Slave
3. Web1
4. Web2
h. help
q. exit
EOF
}

#调用函数来打印菜单
menu
while true
do
read -p "请输入你要选择的主机[h for help]:" host

#通过case语句来匹配用户所输入的主机
case $host in
	1|DB1)
	ssh root@10.1.1.1
	;;
	2|DB2)
	ssh root@10.1.1.2
	;;
	3|web1)
	ssh root@10.1.1.250
	;;
	h|help)
	clear;menu
	;;
	q|quit)
	exit
	;;
esac
done

自己完善功能:
1. 用户选择主机后,需要事先推送公钥;如何判断公钥是否已推
2. 比如选择web1时,再次提示需要做的操作,比如:
clean log
重启服务
kill某个进程

回顾信号:

1) SIGHUP 			重新加载配置    
2) SIGINT			键盘中断^C
3) SIGQUIT      	键盘退出
9) SIGKILL		 	强制终止
15) SIGTERM	    	终止(正常结束),缺省信号
18) SIGCONT	   	继续
19) SIGSTOP	   	停止
20) SIGTSTP     	暂停^Z

欢迎关注学习交流,领取更多资源

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值