- 跳出循环
- shift参数左移指令
- 函数的使用
- 实战-自动备份mysql数据库和nginx服务启动脚本
一、跳出循环
在我们使用循环语句进行循环的过程中,有时间需要在未达到循环结束条件时强制跳出循环,那么shell给我们提供了两个命令来实现该功能:break和continue
break [n]:跳出整个循环,不退出脚本;n表示状态退出码即$?的返回值
continue [n]:跳出本次循环,表示忽略本次循环;n表示忽略循环的次数
exit [n]:表示退出整个脚本,n表示状态退出码(最近一条命令的执行结果)
例1:写一个shell脚本,当按数字键4时退出,否则一直循环
[root@xuegod140 ~]# vim break-continue.sh
[root@xuegod140 ~]# cat break-continue.sh
#!/bin/bash
while true
do
cat <<eof
*********************
Please select your operation:
1.Copy
2.Delete
3.Backup
4.Quit
**********************
eof
read -p “Please enter 1-3 digits:” OP
case $OP in
1)
continue #忽略本次循环,不执行
echo “your select is Copy”
;;
2)
echo “your select is Delete”
;;
3)
echo “your select is Backup”
break #跳出本次循环
;;
4)
echo “Quit”
exit #退出脚本
esac
done
[root@xuegod140 ~]# sh break-continue.sh
*********************
Please select your operation:
1.Copy
2.Delete
3.Backup
4.Quit
**********************
Please enter 1-3 digits:1
*********************
Please select your operation:
1.Copy
2.Delete
3.Backup
4.Quit
**********************
Please enter 1-3 digits:2
your select is Delete
*********************
Please select your operation:
1.Copy
2.Delete
3.Backup
4.Quit
**********************
Please enter 1-3 digits:3
your select is Backup
[root@xuegod140 ~]# sh break-continue.sh
*********************
Please select your operation:
1.Copy
2.Delete
3.Backup
4.Quit
**********************
Please enter 1-3 digits:4
Quit
例2:使用交互式方法,批量添加用户
#!/bin/bash
while :
do
read -p “Please input user prefix & passwd & number: " prefix passwd num
printf "
********************
user prefix: p r e f i x u s e r p a s s w d : prefix user passwd: prefixuserpasswd:passwd
user number: n u m ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ " r e a d − p " A r e y o u s u r e [ y / n ] ? " a c t i o n i f [ " num ******************** " read -p "Are you sure[y/n]?" action if [ " num∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗"read−p"Areyousure[y/n]?"actionif["action” == “y” ];then
break
fi
done
for name in `seq $num`;do
USER=${prefix}${name}
id $USER &>/dev/null
if [ $? -ne 0 ];then
useradd $USER
echo “$passwd” | passwd --stdin $USER &>/dev/null
if [ $? -eq 0 ];then
echo -e "\e[31m $USER \e[0m Created… "
fi
else
echo -e “\e[31m $USER \e[0m exits…”
fi
done
[root@xuegod140 ~]# sh break-2.sh
Please input user prefix & passwd & number: zhang 123456 2
********************
user prefix:zhang
user passwd:123456
user number:2
********************
Are you sure[y/n]?y
zhang1 Created…
zhang2 Created…
[root@xuegod140 ~]# sh break-2.sh
Please input user prefix & passwd & number: zhang 123456 3
********************
user prefix:zhang
user passwd:123456
user number:3
********************
Are you sure[y/n]?y
zhang1 exits…
zhang2 exits…
zhang3 Created…
二、shift参数左移指令
shift命令用于对参数的移动(左移),通常用于在不知道传入参数个数的情况下一次传递每个参数,然后进行相应处理。
如果你的脚本需要10个以上的参数,就需要用到shift命令来访问第10个及其以后的参数
作用:没执行一次,参数序列顺次左移一个位置,$#的值减少1,用于分别处理每个参数,移出去的参数,不再可用
例1:加法计算器
[root@xuegod140 ~]# cat shift.sh
#!/bin/bash
if [ $# -le 0 ];then
echo “没有足够的参数”
exit #退出脚本
fi
sum=0
while [ KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲ -gt 0 ];do …(($sum+KaTeX parse error: Expected 'EOF', got '#' at position 8: 1)) #̲sum=(expr $num+KaTeX parse error: Expected 'EOF', got '#' at position 7: 1) #̲sum=[$sum+$1]
shift
done
echo result is $sum
[root@xuegod140 ~]# sh shift.sh 11 22 33
result is 66
三、函数的使用
1、函数的基本用法
函数是一个脚本代码块,你可以对它进行自定义命名,并且可以再脚本中任意位置使用这个函数,要使用这个函数,只要使用这个函数的函数名称就可以了。
使用函数的好处:模块化,代码可读性强。
语法格式:
方法1:
function name {
commadns
}
方法2:
name(){
commands
}
注意:
(1)name是函数的唯一命令
(2)在shell脚本中函数执行的优先级:别名—函数—命令本身
(3)如果需要使用到命令(commands 命令)
(4)函数的调用,直接在函数后写函数名称
(5)同一个shell脚本中,存在同名的函数,使用最近的一个函数
(6)函数可以当做变量来使用
(7)脚本外的参数,如果需要函数内使用,需要在脚本内使用变量引用
(8)函数内的变量,优先于脚本外的变量(全局变量)
(9)函数内的变量前加local,只限函数内使用(局部变量)
例1:
[root@xuegod140 ~]# vim fun-1.sh
[root@xuegod140 ~]# cat fun-1.sh
#!/bin/bash
function fun_1 {
echo “This is function1”
}
fun_1
[root@xuegod140 ~]# sh fun-1.sh
This is function1
例2:同一个脚本内存在重复函数名,那么以最后一个为准
[root@xuegod140 ~]# vim fun-2.sh
[root@xuegod140 ~]# cat fun-2.sh
#!/bin/bash
fun_2() {
echo “This is fun_2”
}
function fun_2 {
echo “This is 2222”
}
fun_2
[root@xuegod140 ~]# sh fun-2.sh
This is 2222
2、返回值
使用return命令来退出函数并返回特定的退出码
例1:
[root@xuegod140 ~]# cat fun-1.sh
#!/bin/bash
function fun_1 {
echo “This is function1”
ls /etc/passwd
return 3
}
fun_1
[root@xuegod140 ~]# sh fun-1.sh
This is function1
/etc/passwd
[root@xuegod140 ~]# echo $?
3
注:状态码必须要在函数一结束就运行return返回值,取值范围0-255
exit [n]整个脚本就直接退出,返回数字;return只是在函数最后添加一行,然后返回数字,只能让函数后面的命令无法执行,无法强制退出整个脚本的。
3、把函数的值赋给变量
例子:函数名称就相当于是一个变量
[root@xuegod140 ~]# vim fun-3.sh
[root@xuegod140 ~]# cat fun-3.sh
#!/bin/bash
fun_3(){
read -p “Input a value:” va
echo [ [ [va*5]
}
num=KaTeX parse error: Expected 'EOF', got '#' at position 10: (fun_3) #̲()相当于将fun_3这个函数的结果赋值给到num
echo current num is $num
[root@xuegod140 ~]# sh fun-3.sh
Input a value:6
current num is 30
4、函数的参数传递
第一种:通过脚本传递参数给到函数中的位置参数$1
[root@xuegod140 ~]# vim fun-4.sh
[root@xuegod140 ~]# cat fun-4.sh
#!/bin/bash
fun_4(){
rm -f $1
}
fun_4 $1 #相当于外面执行这个命令,将$1这个参数传递给到函数
[root@xuegod140 ~]# touch 5
[root@xuegod140 ~]# sh fun-4.sh 5
[root@xuegod140 ~]# ls 5
ls: cannot access 5: No such file or directory
5、调用函数是直接传递传输
[root@xuegod140 ~]# vim fun-4.sh
[root@xuegod140 ~]# cat fun-4.sh
#!/bin/bash
fun_4(){
rm -f $1
}
fun_4 /root/a.txt # 将后面的内容传递给函数,然后执行函数
[root@xuegod140 ~]# touch a.txt
[root@xuegod140 ~]# sh fun-4.sh a.txt
[root@xuegod140 ~]# ls a.txt
ls: cannot access a.txt: No such file or directory
6、函数中多参数传递和使用方法
[root@xuegod140 ~]# vim fun-5.sh
[root@xuegod140 ~]# cat fun-5.sh
#!/bin/bash
fun_5(){
echo “This 1 $1”
echo “This 2 $2”
echo “This 3 $3”
}
fun_5 11 22 33
[root@xuegod140 ~]# sh fun-5.sh
This 1 11
This 2 22
This 3 33
[root@xuegod140 ~]# vim a.txt
[root@xuegod140 ~]# cat a.txt
123
456
789
111
222
333
[root@xuegod140 ~]# vim fun-5.sh
[root@xuegod140 ~]# cat fun-5.sh
#!/bin/bash
fun_5(){
echo “This 1 $1”
echo “This 2 $2”
echo “This 3 $3”
}
#fun_5 11 22 33
fun_5cat /root/a.txt
[root@xuegod140 ~]# sh fun-5.sh
This 1 123
This 2 456
This 3 789
7、函数中变量的处理
函数中的变量分为两种:局部变量和全局变量
默认情况下,脚本中的变量都是全局变量,你在函数外面定义的变量在函数内也可以使用
例1:
[root@xuegod140 ~]# vim fun-6.sh
[root@xuegod140 ~]# cat fun-6.sh
#!/bin/bash
fun1(){
num1= [ [ [var1*2]
}
read -p “input a num:” var1
fun1
echo the new value is :$num1
[root@xuegod140 ~]# sh fun-6.sh
input a num:6
the new value is :12
四、实战-自动备份mysql数据库脚本和nginx服务启动脚本
1、安装maridb数据库
[root@xuegod140 Packages]# yum -y install mariadb mariadb-server
[root@xuegod140 Packages]# rpm -qa mariadb #安装成功
mariadb-5.5.56-2.el7.x86_64
[root@xuegod140 Packages]# rpm -qf /usr/bin/mysql
mariadb-5.5.56-2.el7.x86_64
[root@xuegod140 Packages]# systemctl start mariadb.service #启动mariadb
[root@xuegod140 Packages]# systemctl status mariadb.service #查看状态
2、登录mysql
[root@xuegod140 Packages]# mysqladmin -u root password “123456” #给root用户配置一个密码
[root@xuegod140 Packages]# mysql -u root -p123456 #登录数据库
MariaDB [(none)]> show databases; #查看数据库,分号必须加上
±-------------------+
| Database |
±-------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
±-------------------+
4 rows in set (0.00 sec)
MariaDB [(none)]> create database xuegod; #创建一个xuegod 的数据库
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> show databases; #查看新增加的数据看
±-------------------+
| Database |
±-------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| xuegod |
±-------------------+
5 rows in set (0.00 sec)
MariaDB [(none)]> use xuegod #选择数据库
Database changed
MariaDB [xuegod]>
MariaDB [xuegod]> create table user (id int); #创建个user表,只有一个id字段
Query OK, 0 rows affected (0.00 sec)
MariaDB [xuegod]> insert into user values(1); #插入一条记录,id字段值1
Query OK, 1 row affected (0.00 sec)
MariaDB [xuegod]> insert into user values(2);#插入一条记录,id字段值2
Query OK, 1 row affected (0.01 sec)
MariaDB [xuegod]> select * from user; #查询user表中的内容
±-----+
| id |
±-----+
| 1 |
| 2 |
±-----+
2 rows in set (0.00 sec)
3、编写备份脚本
[root@xuegod140 Packages]# vim mysql-back-auto.sh
#!/bin/bash
BAKDIR=/data/back/mysql/`date +%Y-%m-%d`
MYSQLDB=xuegod
MYSQLUSR=root
MYSQLPW=123456
#先判断运行脚本的是不是root用户,使用$UID系统变量
if [ $UID -ne 0 ];then
echo “你不是管理员用户,请使用管理员执行此脚本”
sleep 2
exit 0
fi
#判断备份目录是否存在,不存在则创建
#[ ! -d $BAKDIR ] || mkdir $BAKDIR
if [ ! -d $BAKDIR ];then
mkdir -p $BAKDIR
else
echo "This is KaTeX parse error: Expected 'EOF', got '#' at position 22: … exists..." fi #̲使用mysqldump备份数据…MYSQLUSR -p$MYSQLPW $MYSQLDB > B A K D I R / BAKDIR/ BAKDIR/{MYSQLDB}.db.sql
cd $BAKDIR;tar -zcf ${MYSQLDB}.db.tar.gz *.sql
#查找备份目录下以.sql结尾的文件并删除
#find $BAKDIR -name *.sql -type f --delete #第一种方法
#find $BAKDIR -type f -name *.sql -exec rm -rf {} ; #第二种方法
#find $BAKDIR -type f -name *.sql | xargs rm -rf #第三种方法
#如果数据库备份成功,则打印成功,并删除30天以前的目录
if [ $? -eq 0 ];then
echo “This `date +%Y-%m-%d` MySql Backup is success…”
cd $BAKDIR && find . -type d -mtime +30 | xargs rm -rf
echo “The mysql backup successful”
else
echo “This mysql backup not success…”
fi
[root@xuegod140 ~]# sh mysql-back-auto.sh
This 2019-05-04 MySql Backup is success…
The mysql backup successful
2、nginx服务启动脚本
此nginx脚本中使用了函数功能,让脚本具有更强的可读性
安装nginx服务
[root@xuegod140 nginx-1.12.2]# yum -y install pcre-devel.x86_64
[root@xuegod140 nginx-1.12.2]# yum -y install zlib-devel.x86_64
[root@xuegod140 nginx-1.12.2]# ./configure && make -j 4 && make install
[root@xuegod140 ~]# /usr/local/nginx/sbin/nginx
编写脚本
[root@xuegod140 ~]# cat /etc/init.d/nginx
#!/bin/bash
PATH=/date/soft/nginx
DESC=“nginx daemon”
NAME=nginx
DAEMON=$PATH/sbin/$NAME #/date/soft/nginx/sbin/nginx
CONFIGFILE=$PATH/${NAME}.conf
PIDFILE=$PATH/${NAME}.pid
SCRIPTNAME=/etc/init.d/$NAME
[ -x “DAEMON” ] || exit 0
do_start(){
$DAEMON -c $CONFIGFILE || echo “nginx already running…”
}
do_stop(){
$DAEMON -s stop || echo “nginx not running…”
}
do_reload(){
$DAEMON -s reload || echo “nginx can’t reload”
}
case “$1” in
start)
echo -n “Starting D E S C : DESC: DESC:NAME”
do_start
echo “.”
;;
stop)
echo -n “Stopping D E S C : DESC: DESC:NAME”
do_stop
echo “.”
;;
reload|graceful)
echo -n “Reloading $DESC configuration…”
do_reload
echo “.”
;;
restart)
echo -n “Restarting D E S C : DESC: DESC:NAME”
do_stop
do_start
echo “.”
;;
*)
echo “Usage:$SCRIPTNAME{start|stop|reload|restart}” >&2
exit 3
;;
esac
exit 0
3、简易工具箱
[root@xuegod140 ~]# cat tool.sh
#!/bin/bash
#简易工具箱
#显示磁盘情况
Disk(){
lsblk
}
#显示磁盘分区
Diskinfo(){
df -h | grep -v tmpfs
}
#查看内存占用前 10 的进程
Memtop10(){
ps aux --sort -pmem|head -11|awk ‘{print $1,$2, 4 , 4, 4,NF}’
}
#查看占用 CPU 前 10 的进程
Cputop10(){
ps aux --sort -pcpu|head -11|awk ‘{print $1,$2, 4 , 4, 4,NF}’
}
#显示帮劣信息
Help(){
cat<<-eof
±--------- [MENU] ----------------+
| h 显示帮劣信息 |
| m 显示内存占用前 10 |
| u 显示 cpu 占用前 10 |
| d 显示磁盘分区 |
| q 退出程序 |
±----------------------------------+
eof
}
Help
while true
do
read -p "echo -e "\033[31mInput a choose [h for help]\033[0m"" op
case $op in
h)
clear
Help
;;
m)
clear
echo “内存占用前 10 的程序”
Memtop10
;;
d)
clear
echo “查看磁盘分区”
Diskinfo
;;
u)
clear
echo “查看 CPU 占用前 10 的程序”
Cputop10
;;
q)
echo “退出程序”
exit
;;
*)
echo “输入错误,重新选择”
continue
esac
done
本文介绍了shell脚本中跳出循环的break、continue、exit命令,shift参数左移指令,函数的使用方法,包括基本用法、返回值、参数传递等。还给出了自动备份mysql数据库和nginx服务启动脚本的实战案例,以及一个简易工具箱脚本,帮助用户更好地掌握shell脚本编程。

1万+

被折叠的 条评论
为什么被折叠?



