?全套學(xué)習(xí)資料移步至公眾號(hào)【學(xué)神來啦】更多學(xué)習(xí)資料添加扣扣資源群:661308959
本節(jié)所講內(nèi)容:
??22.1 ?跳出循環(huán)
??22.2 ?Shift參數(shù)左移指令
??22.3 ?函數(shù)的使用
??22.4 ?實(shí)戰(zhàn)-自動(dòng)備份mysql數(shù)據(jù)庫和nginx服務(wù)啟動(dòng)腳本
22.1 ?跳出循環(huán)break和continue
在我們使用循環(huán)語句進(jìn)行循環(huán)的過程中,有時(shí)候需要在未達(dá)到循環(huán)結(jié)束條件時(shí)強(qiáng)制跳出循環(huán),那么Shell給我們提供了兩個(gè)命令來實(shí)現(xiàn)該功能:break和continue
Break:跳出整個(gè)循環(huán)
Continue:跳過本次循環(huán),進(jìn)行下次循環(huán)
break概述:跳出當(dāng)前整個(gè)循環(huán)或結(jié)束當(dāng)前循環(huán),在for、while等循環(huán)語句中,用于跳出當(dāng)前所在的循環(huán)體,執(zhí)行循環(huán)體之后的語句,后面如果什么也不加,表示跳出當(dāng)前循環(huán)等價(jià)于break 1,也可以在后面加數(shù)字,假設(shè)break 3表示跳出第三層循環(huán)
continue概述:忽略本次循環(huán)剩余的代碼,直接進(jìn)行下一次循環(huán);在for、while等循環(huán)語句中,用于跳出當(dāng)前所在的循環(huán)體,執(zhí)行循環(huán)體之后的語句?
例1:寫一個(gè)shell菜單,當(dāng)按數(shù)字鍵4時(shí)退出,否則一直循環(huán)顯示
[root@xuegod63 ~]# vim 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后,忽略本次循環(huán)剩余代碼,后面內(nèi)容都不執(zhí)行了,直接進(jìn)行下次一次循環(huán)
echo "your selection is Copy"
?;;
????2)
?echo "your selection is Delete"
?;;
????3)
?echo "your selection is Backup"
?;;
????4)
?echo "your selection is Exit"
?break????#跳出循環(huán)體
?;;
?????*)
echo "invalid selection,please try again"
??esac
done
例2:使用交互式方法批量添加用戶
[root@bogon sh]# vim?useradd.sh
#!/bin/bash
echo ????"*********************"
read -p ?"請(qǐng)輸入要?jiǎng)?chuàng)建的用戶名:" name
read -p ?"請(qǐng)輸入要?jiǎng)?chuàng)建的用戶數(shù):" num
read -p ?"請(qǐng)輸入要?jiǎng)?chuàng)建用戶密碼:" 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 "創(chuàng)建用戶完成,結(jié)果是..."
tail -$num /etc/passwd
vim ??userdel.sh
#!/bin/bash
echo "******************"
read -p "請(qǐng)輸入要?jiǎng)h除的用戶名:" name
read -p "請(qǐng)輸入要?jiǎng)h除的用戶數(shù):" 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 "刪除用戶完成,結(jié)果是..."
tail -$num /etc/passwd
[root@xuegod63 ~]# vim break1.sh
#!/bin/bash
while :
do
????echo -n "輸入 1 到 5 之間的數(shù)字:"
????read aNum
????case $aNum in
????????1|2|3|4|5) echo "你輸入的數(shù)字為 $aNum!"
????????;;
????????*) echo "你輸入的數(shù)字不是 1 到 5 之間的! 游戲結(jié)束"
????????????break
????????;;
????esac
done
[root@xuegod63 ~]# vim continue1.sh
#!/bin/bash
while :
do
????echo -n "輸入 1 到 5 之間的數(shù)字: "
????read aNum
????case $aNum in
????????1|2|3|4|5) echo "你輸入的數(shù)字為 $aNum!"
????????;;
????????*) echo "你輸入的數(shù)字不是 1 到 5 之間的!"
????????????continue
????????????echo "游戲結(jié)束"
????????;;
????esac
done
運(yùn)行代碼發(fā)現(xiàn),當(dāng)輸入大于5的數(shù)字時(shí),會(huì)執(zhí)行continue忽略本次循環(huán),執(zhí)行下一次循環(huán),語句 echo "游戲結(jié)束" 永遠(yuǎn)不會(huì)被執(zhí)行
22.2 ?Shift參數(shù)左移指令
shift命令用于對(duì)參數(shù)的移動(dòng)(左移),通常用于在不知道傳入?yún)?shù)個(gè)數(shù)的情況下依次遍歷每個(gè)參數(shù)然后進(jìn)行相應(yīng)處理(常見于Linux中各種程序的啟動(dòng)腳本)
在掃描處理腳本程序的參數(shù)時(shí),經(jīng)常要用到的shift命令,如果你的腳本需要10個(gè)或10個(gè)以上的參數(shù),你就需要用shift命令來訪問第10個(gè)及其后面的參數(shù)
作用:每執(zhí)行一次,參數(shù)序列順次左移一個(gè)位置,$#的值減1,用于分別處理每個(gè)參數(shù),移出去的參數(shù),不再可用

例子:加法計(jì)算器
[root@xuegod63 ~]# vim shift.sh
#!/bin/bash
if [ $# -le 0 ];then
????????echo "沒有足夠的參數(shù)"
????????exit
fi
sum=0
while [ $# -gt 0 ]
do
????????sum=$(( sum + $1 ))
????????shift
????????#shift 2
done
echo "結(jié)果是" $sum
測(cè)試:
[root@xuegod63 ~]# bash shift.sh??11 2 3 4
result is 20
使用shift 2
sh shift.sh12345678
result is 16
22.3 ?函數(shù)的使用
函數(shù)是一個(gè)腳本代碼塊,你可以對(duì)它進(jìn)行自定義命名,并且可以在腳本中任意位置使用這個(gè)函數(shù),要使用這個(gè)函數(shù),只要使用這個(gè)函數(shù)名稱就可以了。使用函數(shù)的好處:模塊化,代碼可讀性強(qiáng)。
22.3.1 ?函數(shù)創(chuàng)建語法
方法1:
function name {
commands
}
注意:name是函數(shù)唯一的名稱
方法2:name后面的括號(hào)表示你正在定義一個(gè)函數(shù)
name(){
commands
}
調(diào)用函數(shù)語法:
函數(shù)名?參數(shù)1 參數(shù)2 …
調(diào)用函數(shù)時(shí),可以傳遞參數(shù)。在函數(shù)中用$1、$2…來引用傳遞的參數(shù)
22.3.2 ?函數(shù)的使用
例1:
[root@xuegod63 ~]# cat fun1.sh
#!/bin/bash
function fun_1 {????#定義函數(shù)
????????echo "this is function"
}
fun1???#調(diào)用函數(shù)
注意:函數(shù)名的使用,如果在一個(gè)腳本中定義了重復(fù)的函數(shù)名,那么以最后一個(gè)為準(zhǔn)
[root@xuegod63 ~]# vim?fun2.sh
#!/bin/bash
function fun1 {
????????echo "this is function"
}
function fun1 {
????????echo "this is 2222222"
}
fun1
[root@xuegod63 ~]# bash fun2.sh
this is 2222222
22.3.3 ?返回值
使用return命令來退出函數(shù)并返回特定的退出碼
例1:
[root@xuegod63 ~]# vim fun3.sh
#!/bin/bash
function fun1 {
????????echo "this is function"
????????ls /etc/passwd
????????return 3
????????echo "我不會(huì)被執(zhí)行"
}
fun1
[root@xuegod63 ~]# bash fun3.sh ??#查看結(jié)果
this is function
/etc/passwd
[root@xuegod63 ~]# echo $?
3
注:狀態(tài)碼的取值范圍(0~255)
exit 數(shù)字 和return 數(shù)字的區(qū)別?
exit整個(gè)腳本就直接退出,返回?cái)?shù)字 ?
return 只是在函數(shù)最后添加一行,然后返回?cái)?shù)字,只能讓函數(shù)后面的命令不執(zhí)行,無法強(qiáng)制退出整個(gè)腳本。
22.3.4 ?把函數(shù)值賦給變量使用
例子: 函數(shù)名就相當(dāng)于一個(gè)命令
[root@xuegod63 ~]# vim?fun4.sh
#!/bin/bash
fun1(){
????????read -p "Input a number: " va
????????echo $[$va*5]
}
num=$(fun1)
echo current num is $num
[root@xuegod63 ~]# sh fun4.sh
Input a value: 22
current num is 110
22.3.5 ?函數(shù)的參數(shù)傳遞
第一種:通過腳本傳遞參數(shù)給函數(shù)中的位置參數(shù)$1
[root@xuegod63 ~]# vim?fun5.sh
#!/bin/bash
fun1() {
ls?$1
}
fun1 $1 ??
#!/bin/bash
fun1() {
ls?$1
}
fun1 ??#這里如果不寫$1 ,函數(shù)獲取不到$1的值
sh ?fun5.sh ?/tmp
第二種:調(diào)用函數(shù)時(shí)直接傳遞參數(shù)
[root@xuegod63 ~]# touch ?/root/a.txt??#創(chuàng)建一個(gè)測(cè)試文件
[root@xuegod63 ~]# vim fun5.sh
#!/bin/bash
fun1(){
????????rm -rf $1
}
fun1 /root/a.txt
[root@xuegod63 ~]# bash fun5.sh ???#測(cè)試
[root@xuegod63 ~]# ls /root/a.txt
ls: 無法訪問/root/a.txt: 沒有那個(gè)文件或目錄
第三種:函數(shù)中多參數(shù)傳遞和使用方法
[root@xuegod63 ~]# vim fun6.sh
#!/bin/bash
fun() {
????????echo $[$1*5]
????????echo $[$2*2]
????????echo $[$3*3]
}
fun 5 6 $3 ??
[root@xuegod63 ~]# bash fun6.sh 1 2 7??#測(cè)試
25
12?
21
22.3.6 ?函數(shù)中變量的處理
函數(shù)使用的變量類型有兩種:局部變量、全局變量。
1、全局變量,默認(rèn)情況下,你在腳本中定義的變量都是全局變量,你在函數(shù)外面定義的變量在函數(shù)內(nèi)也可以使用
例子:
[root@xuegod63 ~]# vim?fun7.sh
#!/bin/bash
function fun {
????????num=$[var*2]
}
read -p "input a number:" var
fun
echo the new value is: $num
[root@xuegod63 ~]# bash fun7.sh
input a num:2
the new value is: 4
2、局部變量
??不能被引用到函數(shù)外
定義方法:local value
[root@ xuegod63 ~]# vim?fun8.sh
#!/bin/bash
?function fun(){
?????local temp=$[ $value + 5 ] ?# 定義temp為局部變量,只在函數(shù)內(nèi)生效
?????echo "local temp is $temp"
?????result=$[ $temp *2 ]
?}
?temp=4 ??# 這兩個(gè)變量是全局變量
?value=6
?fun
?echo "The result is $result"
?if [ $temp -gt $value ];then ?# 此處的temp變量是temp=4這個(gè)全局變量,并不是fun中的局部變量
?????echo "temp大于value,temp的值是$temp"
?else
?????echo "temp不大于value,temp的值是$temp" ????
fi
[root@xuegod63 ~]# bash fun8.sh
local temp is 11
The result is 22
temp不大于value,temp的值是4
22.4 ?實(shí)戰(zhàn)自動(dòng)備份mysql數(shù)據(jù)庫腳本和nginx服務(wù)啟動(dòng)腳本
22.4.1 ?自動(dòng)備份mysql數(shù)據(jù)庫腳本
從centos7.0開始,系統(tǒng)中自帶的mysql數(shù)據(jù)庫包,改為mariadb數(shù)據(jù)庫。
MariaDB數(shù)據(jù)庫概述:MariaDB數(shù)據(jù)庫管理系統(tǒng)是MySQL的一個(gè)分支,主要由開源社區(qū)在維護(hù),采用GPL授權(quán)許可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能輕松成為MySQL的代替品。MariaDB由MySQL的創(chuàng)始人Michael Widenius(邁克爾·維德紐斯)主導(dǎo)開發(fā),他早前曾以10億美元的價(jià)格,將自己創(chuàng)建的公司MySQL AB賣給了SUN,此后,隨著SUN被甲骨文收購,MySQL的所有權(quán)也落入Oracle的手中。MariaDB名稱來自Michael Widenius的女兒Maria(瑪麗亞)的名字。
甲骨文公司收購了MySQL后,有將MySQL閉源的潛在風(fēng)險(xiǎn),因此社區(qū)采用分支的方式來避開這個(gè)風(fēng)險(xiǎn)。 過去一年中,大型互聯(lián)網(wǎng)用戶以及Linux發(fā)行商紛紛拋棄MySQL,轉(zhuǎn)投MariaDB陣營。MariaDB是目前最受關(guān)注的MySQL數(shù)據(jù)庫衍生版,也被視為開源數(shù)據(jù)庫MySQL的替代品。
安裝mariadb數(shù)據(jù)庫:
[root@xuegod63 ~]# yum -y install mariadb mariadb-server
#?mariadb?是mysql的客戶端命令 ;?mariadb-server?是mysql服務(wù)端命令
[root@xuegod63 ~]# rpm -ql?mariadb
[root@xuegod63 ~]# systemctl start mariadb
登錄mysql:
[root@xuegod63 ~]# mysqladmin ?-u root password "123456"???#給root用戶配置一個(gè)密碼123456
[root@xuegod63 ~]# mysql -u root -p123456??#登錄mysql數(shù)據(jù)庫
MariaDB [(none)]> show databases;
MariaDB [(none)]> create database xuegod??;????#創(chuàng)建xuegod數(shù)據(jù)庫
MariaDB [(none)]> use xuegod;????????#選擇數(shù)據(jù)庫
MariaDB [xuegod]> create table user (id int);???#創(chuàng)建user表,只有一個(gè)id字段
MariaDB [xuegod]> insert into user values(1);???#插入一條記錄,id字段值1
MariaDB [xuegod]> insert into user values(2);???#插入一條記錄,id字段值2
MariaDB [xuegod]> select * from user;???#查看表中的數(shù)據(jù)
+------+
| id ??|
+------+
| ???1 |
| ???2 |
+------+
mysql自動(dòng)化備份腳本:
思路:
1、檢查一下運(yùn)行環(huán)境: 目錄是否存在,時(shí)間,權(quán)限,用戶
2、運(yùn)行要執(zhí)行的命令:備份,導(dǎo)出數(shù)據(jù)。。。
3、把命令執(zhí)行過程中的沒有用的文件刪除一下
4、彈出命令運(yùn)行成功的消息
[root@localhost shell]# vim?mysql-back-auto.sh
#!/bin/bash
# 自動(dòng)備份mysql腳本
# 定義變量
BAKDIR=/data/backup/mysql
MYSQL_DATABASE=xuegod
FILENAME=${MYSQL_DATABASE}_`date +%Y-%m-%d`.sql
MYSQL_USER=root
MYSQL_PASSWORD=123456
# 腳本必須是root用戶才能運(yùn)行
if [ $UID ?-ne 0 ];then
echo 腳本必須root用戶運(yùn)行
exit 0
fi
# 判斷目錄是否存在,不存在則新建,否則如果備份文件存在則退出腳本
if [ ! -d $BAKDIR ];then
????????mkdir -p $BAKDIR
elif [ -f $BAKDIR/${FILENAME}.tar.gz ];then
????????echo "備份文件已存在"
????????exit 1
fi
#使用mysqldump備份數(shù)據(jù)庫
/usr/bin/mysqldump -u${MYSQL_USER} -p${MYSQL_PASSWORD} ${MYSQL_DATABASE} > ${BAKDIR}/${FILENAME}
cd $BAKDIR && tar -czf ${FILENAME}.tar.gz ${FILENAME}
#查找備份目錄下以.sql結(jié)尾的文件并刪除(不建議)
#[ $? -eq 0 ] && find $BAKDIR -type f -name *.sql -exec rm -rf {} \;
#打包命令執(zhí)行成功了,提示成功,然后刪除100天以前的備份文件
[ $? -eq 0 ] && echo "$FILENAME 數(shù)據(jù)庫備份成功"
cd $BAKDIR && find . -type f -mtime +100 -exec rm -rf {} \;
ls $BAKDIR
tar tvf $BAKDIR/${FILENAME}.tar.gz
加入計(jì)劃任務(wù)
crontab -e
0 3 * * * /bin/bash /root/mysql-back-auto.sh
22.4.1??nginx編譯腳本
此nginx腳本中使用了函數(shù)功能,讓腳本具有更強(qiáng)的可讀性
[root@xuegod63 ~]# vim setup_nginx.sh
#!/bin/bash
#編譯安裝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}存在,繼續(xù)編譯安裝步驟"
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 "進(jìn)入${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 "編譯失敗請(qǐng)檢查!"
exit 1
fi
fi
fi
}
make1
[root@xuegod63 ~]# sh setup_nginx.sh
22.4.2 ?nginx服務(wù)啟動(dòng)腳本
此nginx腳本中使用了函數(shù)功能,讓腳本具有更強(qiáng)的可讀性
[root@xuegod63 ~]# vim /etc/init.d/nginx????
#!/bin/bash
#chkconfig: 2345 80 90
#description:nginx run
# nginx啟動(dòng)腳本
PATH_NGINX=/usr/local/nginx ?????#nginx路徑
DESC="nginx daemon" ??????#nginx描述
NAME=nginx
DAEMON=$PATH_NGINX/sbin/$NAME ??#/usr/local/nginx/sbin/nginx #nginx命令的絕對(duì)路徑
PIDFILE=$PATH_NGINX/logs/${NAME}.pid
SCRIPTNAME=/etc/init.d/$NAME
[ -x "$DAEMON" ] || exit 0 ??#不存在可執(zhí)行的文件,則退出
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@xuegod63 ~]# chmod +x /etc/init.d/nginx
[root@xuegod63 ~]# chkconfig --add /etc/init.d/nginx
[root@xuegod63 ~]# chkconfig nginx on
[root@xuegod63 ~]# chkconfig --list
[root@xuegod63 ~]# systemctl status nginx
[root@xuegod63 ~]# systemctl start nginx
[root@xuegod63 ~]# systemctl status?nginx
更多學(xué)習(xí)資料請(qǐng)移步至公眾號(hào)【學(xué)神來啦】