想要獲取更多學(xué)習(xí)資料,關(guān)注公眾號(hào)學(xué)神來啦
本節(jié)所講內(nèi)容:
21.1 ?case-流程控制語句
21.2 ?循環(huán)語句
21.3 ?while循環(huán)語句和循環(huán)嵌套
21.4 ?實(shí)戰(zhàn)-3個(gè)shell腳本實(shí)戰(zhàn)
21.1 ?流程控制語句:case
控制語句:用來實(shí)現(xiàn)對(duì)程序流程的選擇、循環(huán)蚤假、轉(zhuǎn)向和返回等進(jìn)行控制。case是開關(guān)語句的一個(gè)組成部分田绑;
它是根據(jù)變量的不同進(jìn)行取值比較勤哗,然后針對(duì)不同的取值分別執(zhí)行不同的命令操作
適用于多分支,是一個(gè)多選擇語句
case?????變量或表達(dá)式?????in
?????? ???????變量或表達(dá)式1)
?????????????????????命令序列1
?????????????????????掩驱;芒划;
????????????變量或表達(dá)式2)
?????????????????????命令序列2
?????????????????????;欧穴;
?????????????????????……
???????????????????? *)??
?????????????????????默認(rèn)命令序列
?esac
case語句執(zhí)行流程控制:
執(zhí)行流程:
首先使用“變量或表達(dá)式”的值與值1進(jìn)行比較民逼,若取值相同則執(zhí)行值1后的命令序列,直到遇見雙分號(hào)“涮帘;拼苍; ”后跳轉(zhuǎn)至esac,表示分支結(jié)束调缨;
若與值1不相匹配疮鲫,則繼續(xù)與值2 進(jìn)行比較,若取值相同則執(zhí)行值2 后的命令序列弦叶,直到遇見雙分號(hào)“俊犯;; ”后跳轉(zhuǎn)至esac伤哺,表示結(jié)束分支燕侠。
依次類推者祖,若找不到任何匹配的值,則執(zhí)行默認(rèn)模式“ *) ”后的命令序列绢彤,直到遇見esac后結(jié)束分支
注意事項(xiàng):
“變量或表達(dá)式”后面必須為單詞in七问,每一個(gè)“變量或表達(dá)式”的值必須以右括號(hào)結(jié)束。取值可以為變量或常數(shù)茫舶。匹配發(fā)現(xiàn)取值符合某一模式后械巡,其間所有命令開始執(zhí)行直至 ;;
匹配中的值可以是多個(gè)值,通過“|”來分隔
例1:編寫一個(gè)操作文件的腳本
[root@xuegod63 ~]# vim case1.sh
####################################################################
# File Name: case-1.sh
# Author: xuegod
####################################################################
#!/bin/bash
cat <<eof
****************
** 1. backup ?**
** 2. copy ???**
** 3. quit ???**
****************
eof
read -p "請(qǐng)輸入您的選擇: " OP
case $OP in
1|backup)
echo "BACKUP......"
;;
2|copy)
echo "COPY....."
;;
3|quit)
exit
;;
*)
echo error
esac
sh ?case1.sh
例2:編寫一個(gè)啟動(dòng)apache服務(wù)腳本
[root@xuegod63 ~]# yum -y?install httpd
[root@xuegod63 ~]# vim ?case2.sh
#!/bin/bash
case $1 in
????????start)
????????????????/usr/bin/systemctl $1 httpd
????????????????/usr/bin/ps aux | grep httpd | grep -v grep
????????????????echo "httpd start"
?????????????????????????;;
????????stop)
????????????????/usr/bin/systemctl $1 httpd
????????????????/usr/bin/ps aux | grep httpd | grep -v grep
????????????????echo "httpd stop"
?????????????????????????;;
????????restart)
????????????????/usr/bin/systemctl $1 httpd
????????????????/usr/bin/ps aux | grep httpd | grep ?-v grep
????????????????echo "httpd restart"
?????????????????????????;;
????????status)
????????????????/usr/bin/systemctl $1 httpd | grep -v grep
????????????????????????;;
????????*)
????????????????echo "please input start | stop | restart | status"
esac
[root@xuegod63 ~]# sh case2.sh
21.2 ?循環(huán)語句
21.2.1 ?for-do-done
語法格式:
for var in list ???#for后跟var(var相當(dāng)于一個(gè)變量)list(相當(dāng)于一個(gè)列表)
do
??commands
done
或:
for var in list ; do
??commands
done
取值列表有多種取值方式奇适,比如
可以直接讀取in 后面的值坟比,默認(rèn)以空格做分隔
[root@xuegod63 ~]# vim?for1.sh
#!/bin/bash
for var in a1 b1 c1 d1
do
echo the text is $var
done
列表中的復(fù)雜值,可以使用引號(hào)或轉(zhuǎn)義字符”\”來加以約束
[root@xuegod63 ~]# vim for2.sh ??
#!/bin/bash
for var in a1 b1 ?'c1 d1' ?e2 ?'hello world'
do
????????echo the text is $var
done
[root@xuegod63 ~]# vim?for3.sh
#!/bin/bash
for var in a1 b\'1 'c1 d1' e2 'hello world'
do
echo the text is $var
done
從變量中取值
[root@xuegod63 ~]# vim?for4.sh
#!/bin/bash
list="a1 b1 c1 d1"
for i in $list
do
echo list is a $i
done
4嚷往、從命令中取值
[root@xuegod63 ~]# vim?for5.sh ??#默認(rèn)以以空格做分隔符
#!/bin/bash
for i in `cat /etc/hosts`
do
echo "$i"
done
sh ??for-5.sh
127.0.0.1
localhost
localhost.localdomain
localhost4
localhost4.localdomain4
::1
localhost
localhost.localdomain
localhost6
localhost6.localdomain6
5葛账、自定義shell分隔符
默認(rèn)情況下,base shell會(huì)以空格皮仁、制表符籍琳、換行符做為分隔符。通過IFS來自定義為分隔符
指定單個(gè)字符做分隔符:
IFS=: ??#以:冒號(hào)做分隔符
可以指定多個(gè)
如 IFS='\n: "; ' ???#這個(gè)賦值會(huì)將反斜杠贷祈、n趋急、冒號(hào)、雙引號(hào)势誊、分號(hào)作為字段分隔符呜达。
注:$'\n'與'\n'時(shí)的區(qū)別
IFS='\n' ???#將字符\和字符n作為字段分隔符。
IFS=$'\n' ??#使用換行符做為字段分隔符粟耻。
[root@xuegod63 ~]# vim for6.sh??#指定以\n回車做為 for語句的分隔符
#!/bin/bash
IFS=$'\n'
for i in `cat /etc/hosts`
do
echo "$i"
done
?[root@xuegod63 ~]# vim for6.sh???#以:冒號(hào)做分隔符
#!/bin/bash
IFS=:
for i in `cat /etc/hosts`
do
echo $i
done
6查近、C語言風(fēng)格的for
語法格式:
for ((i=0;i<10;i++))
do
???commmands
done
例1:?jiǎn)蝹€(gè)變量 輸出1到10之間的數(shù)字
[root@xuegod63 ~]# vim for7.sh
#!/bin/bash
for ((i=1?;?i<=10 ;?i++ ?))
do
echo num is $i
done
for ((??i=1??;?i<=10 ?;??????))???#i=1 只賦值一次。然后執(zhí)行 i <= 10
do
echo num is $i
i=$(($i+1))????# i++在這里執(zhí)行挤忙。 當(dāng)for循環(huán)體中所有命令執(zhí)行完后霜威,再執(zhí)行i++
done
例2:多個(gè)變量。 同時(shí)輸出1-9的升序和降序
[root@xuegod63 ~]# vim for9.sh
#!/bin/bash
for ((a=1,b=9 ;a<10;a++,b--))
do
echo num is $a - $b
done
[root@xuegod63 ~]# vim for9.sh
#!/bin/bash
for ((a=1,b=9;a<10,b>5;a++,b--))
do
echo num is $a - $b
done
21.3 ?while循環(huán)語句和循環(huán)嵌套
21.3.1 ?while-do-done
重復(fù)測(cè)試指令的條件册烈,只要條件成立就反復(fù)執(zhí)行對(duì)應(yīng)的命令操作戈泼,直到命令不成立或?yàn)榧伲?/b>
語法格式如下:
while?測(cè)試命令
do
命令
done
注意:避免陷入死循環(huán) ?while true
例1:降序輸出10到1的數(shù)字
[root@xuegod63 ~]# vim while1.sh
#!/bin/bash
var=10
while [ $var -gt 0 ]
do
echo $var
var=$[$var-1]
?????#var=$(($var-1))
?????#let var--
done
例2:輸出如下圖兩數(shù)相乘的效果
自增操作 ?let var++ ?
自減操作 ?let var-- ?
[root@xuegod63 ~]# vim while2.sh
#!/bin/bash
num=1
while [ $num -lt 10 ]
do
????????sum=$(( ?$num * $num ))
????????echo ?"$num * $num = $sum"
????????((num++))
# ??????let num++
done
21.3.2 ?嵌套循環(huán)
例1:批量添加a.txt文件5個(gè)用戶
[root@xuegod63 ~]# vim?a.txt???#添加5個(gè)用戶
cp
cd
ls
find
ln
編寫腳本的思路
1 ?明確腳本的功能
2 ?編寫腳本時(shí)會(huì)使用到那些命令 ? ?useradd ???passwd ??for
3 ?把變化的數(shù)據(jù)使用變量表示
4 ?選擇適合的流程控制 ?(選擇 赏僧、 循環(huán) 大猛、分支)
[root@xuegod63 ~]# vim add.sh
#!/bin/bash
for name in `cat /root/a.txt`
#for name in $(cat /root/a.txt)
do
????????id $name &> /dev/null
????????if [ $? -ne 0 ];then
????????????????useradd $name
????????????????echo "123456" |passwd --stdin $name &> /dev/null
????????????????echo "user $name created"
????????else
????????????????echo "user $name is exist"
????????fi
done
注:&> 是正確和錯(cuò)誤的信息都重定向到/dev/null里面,相當(dāng)于1> /dev/null 2>&1 這個(gè)寫法
例2 :打印九九乘法表
注:外層循環(huán)循環(huán)行淀零,內(nèi)層循環(huán)循環(huán)列
規(guī)律: ?內(nèi)層循環(huán)的變量<=外層循環(huán)的變量
echo -n 代表不換行
[root@xuegod63 ~]# vim?forfor.sh
#!/bin/bash
for i in ?`seq 9`
do
?????????for j in `seq $i`
?????????do
??????????????echo ?-n ?"$i*$j= `echo $(($i*$j))` ?"
?????????done
????????echo " ?"
done
21.4 ?實(shí)戰(zhàn)-3個(gè)shell腳本實(shí)戰(zhàn)
21.4.1 ?實(shí)戰(zhàn)-將/opt目錄下所有的日志文件全自動(dòng)打包
[root@xuegod63 ~]# vim log-back.sh
#!/bin/bash
SRC_DIR=/var/log/
DES_DIR=/opt/backup/`date +%Y%m%d`
#如果目標(biāo)目錄不存在胎署,則創(chuàng)建目標(biāo)目錄
if
[ ! -d ?$DES_DIR ] ; then
????????mkdir -p $DES_DIR
fi
#遍歷找到的日志文件并打包
for i in ?`find ?$SRC_DIR ?-name "*.log"`
do
????????tar ?czf ?$i.gz ?$i &> /dev/null
done
#剪切打包的日志文件到目標(biāo)目錄
mv /var/log/*.gz $DES_DIR
ls -lh $DES_DIR
echo "The scripts exec end, Files tar successfully !"
21.4.2 ?實(shí)戰(zhàn)-找出192.168.1.1-10網(wǎng)段中,服務(wù)器已經(jīng)關(guān)機(jī)的IP地址
[root@xuegod63 ~]# vim ping.sh
#!/bin/bash
i=1
for (( i=1;i<=10;i++ ))
#?for I in {1..10}
# for I in `seq 10`
do
??ping ?-c ?3 ?192.168.100.$i &> /dev/null
??if ?[ $? -ne 0 ];then
?????echo 192.168.100.$i is shutdown
??fi
done
21.4.3 ?批量創(chuàng)建帳號(hào)并生成隨機(jī)密碼
[root@xuegod63 ~]# vim adduser.sh
#!/bin/bash
for i in xuegod{1..10}
do
??????useradd $i
??????if [ $? -eq 0 ];then
????????echo "create ${i} user is successfully!"
??????else
????????echo "create ${i} user is failed!"
??????fi
??????pass=`date +%s|md5sum|cut -c 1-8`
??????sleep 1
??????echo "$i:$pass" >> /tmp/passwd.log
??????echo $pass |passwd --stdin $i &> /dev/null
??????if [ $? -eq 0 ];then
????????echo " ${i} user change passwd is successfully!"
??????else
????????echo " ${i} user change passwd is failed!"
??????fi
done
注意:%s 總秒數(shù)窑滞。起算時(shí)間為1970-01-01 00:00:00 UTC
更多學(xué)習(xí)資料請(qǐng)移步至公眾號(hào)【學(xué)神來啦】