linux運(yùn)維零基礎(chǔ)學(xué)習(xí)課程:跳出循環(huán)-shift參數(shù)左移-函數(shù)的使用

?全套學(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é)神來啦】

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容