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

欢迎关注学习交流,领取更多资源
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 9,945评论 0 5
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 7,891评论 2 9
  • 本文是对Linux shell编程的一个学习比较,共包括如下章节的内容: 概述 基本语法 结构化语句 函数 小结 ...
    我是老薛阅读 4,256评论 0 5
  • 第 2 章 SHELL 基础知识2.1 shell脚本我们在上面简单介绍了一下什么是shell脚本,现在我们来进一...
    LiWei_9e4b阅读 5,457评论 0 0
  • Shell入门 什么是shell? Shell其实是一个命令解释器,作用是解释执行用户输入的命令以及程序等,用户每...
    酷酷的伟阅读 3,150评论 0 1