当前位置 : 主页 > 操作系统 > centos >

Linux 云计算集群架构师->第二十二章 跳出循环-shift 参数左移-函数的使用

来源:互联网 收集:自由互联 发布时间:2022-09-29
第二十二章 跳出循环-shift 参数左移-函数的使用 (上课时间2021-07-19,笔记整理时间2021-07-27) 本节所讲内容: 22.1 跳出循环 22.2 Shift 参数左移指令 22.3 函数的使用 22.4 实战-自动备份 mysq

第二十二章 跳出循环-shift 参数左移-函数的使用

(上课时间2021-07-19,笔记整理时间2021-07-27)

本节所讲内容:

22.1 跳出循环

22.2 Shift 参数左移指令

22.3 函数的使用

22.4 实战-自动备份 mysql 数据库和 nginx 服务启动脚本

22.1 跳出循环 break 和 continue

在我们使用循环语句进行循环的过程中,有时候需要在未达到循环结束条件时强制跳出循环,那么Shell 给我们提供了两个命令来实现该功能:break 和 continue

Break:跳出整个循环

Continue:跳过本次循环,进行下次循环

break 概述:跳出当前整个循环或结束当前循环,在 for、while 等循环语句中,用于跳出当前所在的循环体,执行循环体之后的语句,后面如果什么也不加,表示跳出当前循环等价于 break 1,也可以在后面加数字,假设 break 3 表示跳出第三层循环

continue 概述:忽略本次循环剩余的代码,直接进行下一次循环;在 for、while 等循环语句中,用于跳出当前所在的循环体,执行循环体之后的语句

写一个 shell 菜单,当按数字键 4 时退出,否则一直循环显示

[root@CentOS83 ~]# vim break-continue.sh [root@CentOS83 ~]# cat break-continue.sh #! /bin/sh while true do echo "*******************************" echo "Please select your operation:" echo " 1 Copy" echo " 2 Delete" echo " 3 Backup" echo " 4 Quit" echo "*******************************" read op case $op in 1) continue #这里加了 continue 后,忽略本次循环剩余代码,后面内容都不执行了,直接进行下次一次循环 echo "your selection is Copy" ;; 2) echo "your selection is Delete" ;; 3) echo "your selection is Backup" ;; 4) echo "your selection is Exit" break #跳出循环体 ;; *) echo "invalid selection,please try again" esac done [root@CentOS83 ~]# sh break-continue.sh ******************************* Please select your operation: 1 Copy 2 Delete 3 Backup 4 Quit *******************************

使用交互式方法批量添加用户

[root@CentOS83 ~]# vim usersadd.sh [root@CentOS83 ~]# cat usersadd.sh #!/bin/bash echo "*********************" read -p "请输入要创建的用户名:" name read -p "请输入要创建的用户数:" num read -p "请输入要创建用户密码:" pas echo "*********************" for ((i=1;i<=$num;i=i+1)) do useradd $name$i &> /dev/null echo "$pas" | passwd --stdin $name$i &> /dev/null done echo "创建用户完成,结果是..." tail -$num /etc/passwd [root@CentOS83 ~]# sh usersadd.sh ********************* 请输入要创建的用户名:diors 请输入要创建的用户数:1 请输入要创建用户密码:123456 ********************* 创建用户完成,结果是... diors1:x:1026:1026::/home/diors1:/bin/bash

使用交互式方法批量删除用户

[root@CentOS83 ~]# vim userdel.sh [root@CentOS83 ~]# cat userdel.sh #!/bin/bash echo "******************" read -p "请输入要删除的用户名:" name read -p "请输入要删除的用户数:" num echo "******************" for ((i=1;i<=$num;i++ )) do if [ $i -eq 4 ];then continue #break else userdel -r $name$i &> /dev/null fi done echo "删除用户完成,结果是..." tail -$num /etc/passwd [root@CentOS83 ~]# sh userdel.sh ****************** 请输入要删除的用户名:diors 请输入要删除的用户数:1 ****************** 删除用户完成,结果是... lsuser10:x:1025:1025::/home/lsuser10:/bin/bash

**循环1-5 break **

[root@CentOS83 ~]# vim break.sh [root@CentOS83 ~]# cat break.sh #!/bin/bash while : do echo -n "输入 1 到 5 之间的数字:" read aNum case $aNum in 1|2|3|4|5) echo "你输入的数字为 $aNum!" ;; *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束" break ;; esac done [root@CentOS83 ~]# sh break.sh 输入 1 到 5 之间的数字:3 你输入的数字为 3! 输入 1 到 5 之间的数字:6 你输入的数字不是 1 到 5 之间的! 游戏结束

循环1-5 continue

[root@CentOS83 ~]# vim continue.sh [root@CentOS83 ~]# cat continue.sh #!/bin/bash while : do echo -n "输入 1 到 5 之间的数字: " read aNum case $aNum in 1|2|3|4|5) echo "你输入的数字为 $aNum!" ;; *) echo "你输入的数字不是 1 到 5 之间的!" continue echo "游戏结束" ;; esac done [root@CentOS83 ~]# sh continue.sh 输入 1 到 5 之间的数字: 2 你输入的数字为 2! 输入 1 到 5 之间的数字: 6 你输入的数字不是 1 到 5 之间的! 输入 1 到 5 之间的数字:

运行代码发现,当输入大于 5 的数字时,会执行 continue 忽略本次循环,执行下一次循环,语句echo "游戏结束" 永远不会被执行

22.2 Shift 参数左移指令

shift 命令用于对参数的移动(左移),通常用于在不知道传入参数个数的情况下依次遍历每个参数然后进行相应处理(常见于 Linux 中各种程序的启动脚本)

在扫描处理脚本程序的参数时,经常要用到的 shift 命令,如果你的脚本需要 10 个或 10 个以上的参数,你就需要用 shift 命令来访问第 10 个及其后面的参数

作用:每执行一次,参数序列顺次左移一个位置,$#的值减 1,用于分别处理每个参数,移出去的参数,不再可用

image-20210726132703888

加法计算器

[root@CentOS83 ~]# vim shift.sh [root@CentOS83 ~]# cat shift.sh #/bin/bash if [ $# -le 0 ];then echo "没有足够的参数" exit fi sum=0 while [ $# -gt 0 ] do sum=$(( sum + $1 )) shift #shift 2 done echo "结果是" $sum [root@CentOS83 ~]# bash shift.sh 10 20 25 35 40 #测试 结果是 130 [root@CentOS83 ~]# bash shift.sh 10 20 30 40 50 60 70 80 使用 shift 2 结果是 160

22.3 函数的使用

函数是一个脚本代码块,你可以对它进行自定义命名,并且可以在脚本中任意位置使用这个函数,要使用这个函数,只要使用这个函数名称就可以了。使用函数的好处:模块化,代码可读性强。

22.3.1 函数创建语法

方法 1:

function name {

commands

}

注意:name 是函数唯一的名称

方法 2:name 后面的括号表示你正在定义一个函数

name(){

commands

}

调用函数语法:

函数名 参数 1 参数 2 …

调用函数时,可以传递参数。在函数中用$1、$2…来引用传递的参数

22.3.2 函数的使用

[root@CentOS83 ~]# vim fun.sh [root@CentOS83 ~]# cat fun.sh #!/bin/bash function fun_1 { #定义函数 echo "this is function" } fun1 #调用函数

注意:函数名的使用,如果在一个脚本中定义了重复的函数名,那么以最后一个为准

[root@CentOS83 ~]# vim fun1.sh [root@CentOS83 ~]# cat fun1.sh #!/bin/bash function fun1 { echo "this is function" } function fun1 { echo "this is 123123" } fun1 [root@CentOS83 ~]# bash fun1.sh #测试 this is 123123

22.3.3 返回值

使用 return 命令来退出函数并返回特定的退出码

[root@CentOS83 ~]# vim fun2.sh [root@CentOS83 ~]# cat fun2.sh #!/bin/bash function fun1 { echo "this is function" ls /etc/passwd return 3 echo "我不会执行" } fun1 [root@CentOS83 ~]# bash fun2.sh #测试 this is function /etc/passwd [root@CentOS83 ~]# echo $? 3

注:状态码的取值范围(0~255)

exit 数字 和 return 数字的区别?

exit 整个脚本就直接退出,返回数字

return 只是在函数最后添加一行,然后返回数字,只能让函数后面的命令不执行,无法强制退出整个脚本。

22.3.4 把函数值赋给变量使用

[root@CentOS83 ~]# vim fun3.sh [root@CentOS83 ~]# cat fun3.sh #!/bin/bash fun1(){ read -p "input a number:" va echo $[$va*5] } num=$(fun1) echo current num is $num [root@CentOS83 ~]# bash fun3.sh #测试 input a number:23 current num is 115

22.3.5 函数的参数传递

第一种:通过脚本传递参数给函数中的位置参数$1

[root@CentOS83 ~]# vim fun4.sh [root@CentOS83 ~]# cat fun4.sh #!/bin/bash fun1(){ ls $1 } fun1 $1 [root@CentOS83 ~]# bash fun4.sh #测试 #!/bin/bash fun1() { ls $1 } fun1 #这里如果不写$1 ,函数获取不到$1 的值

第二种:调用函数时直接传递参数

[root@CentOS83 ~]# vim fun5.sh [root@CentOS83 ~]# cat fun5.sh #!/bin/bash fun1(){ rm -rf $1 } fun1 /root/a.txt [root@CentOS83 ~]# bash fun5.sh

第三种:函数中多参数传递和使用方法

[root@CentOS83 ~]# vim fun6.sh [root@CentOS83 ~]# cat fun6.sh #!/bin/bash fun() { echo $[$1*5] echo $[$2*2] echo $[$3*3] } fun 5 6 $3 [root@CentOS83 ~]# bash fun6.sh 5 4 6 #测试 25 12 18

22.3.6 函数中变量的处理

函数使用的变量类型有两种:局部变量、全局变量。

1、全局变量,默认情况下,你在脚本中定义的变量都是全局变量,你在函数外面定义的变量在函数内也可以使用

[root@CentOS83 ~]# vim fun7.sh [root@CentOS83 ~]# cat fun7.sh #!/bin/bash function fun { num=$[var*5] } read -p "input a number:" var fun echo the new value is: $num [root@CentOS83 ~]# bash fun7.sh #测试 input a number:5 the new value is: 25

2、局部变量

不能被引用到函数外

定义方法:local value

[root@CentOS83 ~]# vim fun8.sh [root@CentOS83 ~]# cat fun8.sh #!/bin/bash function fun(){ local temp=$[ $value + 5 ] # 定义 temp 为局部变量,只在函数内生效 echo "local temp is $temp" result=$[ $temp *2 ] } temp=4 # 这两个变量是全局变量 value=6 fun echo "The result is $result" if [ $temp -gt $value ];then # 此处的 temp 变量是 temp=4 这个全局变量,并不是 fun 中的局部变量 echo "temp 大于 value,temp 的值是$temp" else echo "temp 不大于 value,temp 的值是$temp" fi [root@CentOS83 ~]# bash fun8.sh local temp is 11 The result is 22 temp 不大于 value,temp 的值是4

22.4 实战自动备份 mysql 数据库脚本和 nginx 服务启动脚本

22.4.1 自动备份 mysql 数据库脚本

从 centos7.0 开始,系统中自带的 mysql 数据库包,改为 mariadb 数据库。

MariaDB 数据库概述:MariaDB 数据库管理系统是 MySQL 的一个分支,主要由开源社区在维护,采用 GPL 授权许可 MariaDB 的目的是完全兼容 MySQL,包括 API 和命令行,使之能轻松成为MySQL 的代替品。MariaDB 由 MySQL 的创始人 Michael Widenius(迈克尔·维德纽斯)主导开发,他早前曾以 10 亿美元的价格,将自己创建的公司 MySQL AB 卖给了 SUN,此后,随着 SUN 被甲骨文收购,MySQL 的所有权也落入 Oracle 的手中。

MariaDB 名称来自 Michael Widenius 的女儿

Maria(玛丽亚)的名字。

甲骨文公司收购了 MySQL 后,有将 MySQL 闭源的潜在风险,因此社区采用分支的方式来避开这个风险。 过去一年中,大型互联网用户以及 Linux 发行商纷纷抛弃 MySQL,转投 MariaDB 阵营。

MariaDB 是目前最受关注的 MySQL 数据库衍生版,也被视为开源数据库 MySQL 的替代品。

安装 mariadb 数据库:

[root@CentOS83 ~]# yum -y remove mariadb* [root@CentOS83 ~]# yum -y install mariadb mariadb-server # mariadb 是 mysql 的客户端命令 ; mariadb-server 是 mysql 服务端命令 [root@CentOS83 ~]# rpm -ql mariadb [root@CentOS83 ~]# systemctl restart mariadb [root@CentOS83 ~]# mysqladmin -u root password "123456" #给 root 用户配置一个密码 123456 [root@CentOS83 ~]# mysql -u root -p123456 MariaDB [(none)]> show databases; #查看所有数据库 MariaDB [(none)]> create database linuxdb; #创建 xuegod 数据库 MariaDB [(none)]> use linuxdb; #选择数据库 Database changed MariaDB [linuxdb]> create table user (id int); #创建 user 表,只有一个 id 字段 Query OK, 0 rows affected (0.076 sec) MariaDB [linuxdb]> insert into user values(1); #插入一条记录,id 字段值 1 Query OK, 1 row affected (0.004 sec) MariaDB [linuxdb]> insert into user values(2); #插入一条记录,id 字段值 2 Query OK, 1 row affected (0.002 sec) MariaDB [linuxdb]> select * from user; #查看表中的数据 +------+ | id | +------+ | 1 | | 2 | +------+ 2 rows in set (0.001 sec)

**mysql 自动化备份脚本:

思路:

1、检查一下运行环境: 目录是否存在,时间,权限,用户

2、运行要执行的命令:备份,导出数据。。。

3、把命令执行过程中的没有用的文件删除一下

4、弹出命令运行成功的消息

[root@CentOS83 ~]# vim mysql-back-auto.sh [root@CentOS83 ~]# cat mysql-back-auto.sh #!/bin/bash # 自动备份 mysql 脚本 # 定义变量 BAKDIR=/data/backup/mysql MYSQL_DATABASE=xuegod FILENAME=${MYSQL_DATABASE}_`date +%Y-%m-%d`.sql MYSQL_USER=root MYSQL_PASSWORD=123456 # 脚本必须是 root 用户才能运行 if [ $UID -ne 0 ];then echo 脚本必须 root 用户运行 exit 0 fi # 判断目录是否存在,不存在则新建,否则如果备份文件存在则退出脚本 if [ ! -d $BAKDIR ];then mkdir -p $BAKDIR elif [ -f $BAKDIR/${FILENAME}.tar.gz ];then echo "备份文件已存在" exit 1 fi #使用 mysqldump 备份数据库 /usr/bin/mysqldump -u${MYSQL_USER} -p${MYSQL_PASSWORD} ${MYSQL_DATABASE} > ${BAKDIR}/${FILENAME} cd $BAKDIR && tar -czf ${FILENAME}.tar.gz ${FILENAME} #查找备份目录下以.sql 结尾的文件并删除(不建议) #[ $? -eq 0 ] && find $BAKDIR -type f -name *.sql -exec rm -rf {} \; #打包命令执行成功了,提示成功,然后删除 100 天以前的备份文件 [ $? -eq 0 ] && echo "$FILENAME 数据库备份成功" cd $BAKDIR && find . -type f -mtime +100 -exec rm -rf {} \; ls $BAKDIR tar tvf $BAKDIR/${FILENAME}.tar.gz

加入计划任务

crontab -e

0 3 * * * /bin/bash /root/mysql-back-auto.sh

22.4.1 nginx 编译脚本

此 nginx 脚本中使用了函数功能,让脚本具有更强的可读性

[root@CentOS83 ~]# vim setup_nginx.sh [root@CentOS83 ~]# cat setup_nginx.sh #编译安装 nginx-1.18.0 #定义变量 prefix=/usr/local/nginx setup_file=nginx-1.18.0.tar.gz setup_dir=/root/ setup_version=nginx-1.18.0 setup_url=http://nginx.org/download/nginx-1.18.0.tar.gz #检查文件是否存在,不存在则下载 check_file(){ if [ ! -f ${setup_dir}${setup_file} ];then cd ${setup_dir} && wget ${setup_url} else cd ${setup_dir} echo "${setup_dir}${setup_file}存在,继续编译安装步骤" fi if [ ! -d ${prefix} ];then mkdir -p /usr/local/nginx else echo "${prefix}存在" fi } make1(){ check_file; if [ -f ${setup_dir}${setup_file} ];then tar -xvf ${setup_dir}${setup_file} if [ $? -eq 0 ];then echo "解压成功" cd ${setup_dir}${setup_version} echo "进入${PWD}目录" yum install -y pcre-devel zlib-devel ./configure --prefix=${prefix} make -j 4 && make install if [ $? -eq 0 ]; then echo "编译完成" exit 0 else echo "编译失败请检查!" exit 1 fi fi fi } make1 [root@CentOS83 ~]# chmod +x setup_nginx.sh [root@CentOS83 ~]# bash setup_nginx.sh

22.4.2 nginx 服务启动脚本

此 nginx 脚本中使用了函数功能,让脚本具有更强的可读性

[root@CentOS83 ~]# vim /etc/init.d/nginx [root@CentOS83 ~]# cat /etc/init.d/nginx #!/bin/bash #chkconfig: 2345 80 90 #description:nginx run # nginx 启动脚本 PATH_NGINX=/usr/local/nginx #nginx 路径 DESC="nginx daemon" #nginx 描述 NAME=nginx DAEMON=$PATH_NGINX/sbin/$NAME #/usr/local/nginx/sbin/nginx #nginx 命令的绝 对路径 PIDFILE=$PATH_NGINX/logs/${NAME}.pid SCRIPTNAME=/etc/init.d/$NAME [ -x "$DAEMON" ] || exit 0 #不存在可执行的文件,则退出 do_start() { [ ! -f "${PIDFILE}" ] && ${DAEMON} || echo -n " nginx already running" ps_aux } do_stop() { [ -f "${PIDFILE}" ] && $DAEMON -s stop || echo -n " nginx not running" } do_reload() { $DAEMON -s reload || echo -n "\n nginx can't reload" } ps_aux() { echo "" ps aux | grep "${NAME}" | grep -v "grep" } case "$1" in start) echo -n "Starting $DESC: $NAME" do_start echo "." ;; stop) echo -n "Stopping $DESC: $NAME" do_stop echo "." ;; reload|graceful) echo -n "Reloading $DESC configuration..." do_reload echo "." ;; restart) echo -n "Restarting $DESC: $NAME" do_stop sleep 1 do_start ;; *) echo "Usage: $SCRIPTNAME {start|stop|reload|restart}" exit 1 ;; esac exit 0 [root@CentOS83 ~]# chmod +x /etc/init.d/nginx [root@CentOS83 ~]# chkconfig --add /etc/init.d/nginx [root@CentOS83 ~]# chkconfig nginx on [root@CentOS83 ~]# chkconfig --list Note: This output shows SysV services only and does not include native systemd services. SysV configuration data might be overridden by native systemd configuration. If you want to list systemd services use 'systemctl list-unit-files'. To see services enabled on particular target use 'systemctl list-dependencies [target]'. jexec 0:off 1:on 2:on 3:on 4:on 5:on 6:off nginx 0:off 1:off 2:on 3:on 4:on 5:on 6:off [root@CentOS83 ~]# systemctl status nginx ● nginx.service - SYSV: nginx run Loaded: loaded (/etc/rc.d/init.d/nginx; generated) Active: inactive (dead) Docs: man:systemd-sysv-generator(8) [root@CentOS83 ~]# systemctl start nginx [root@CentOS83 ~]# systemctl status nginx

总结:

22.1 跳出循环

22.2 Shift 参数左移指令

22.3 函数的使用

22.4 实战-自动备份 mysql 数据库和 nginx 服务启动脚本

网友评论