shell腳本編程學習之路-for循環

1.for循環結構

1.1 for循環結構語法

語法:html

for  變量名 in 變量取值列表

do

指令…

done

提示:在此結構中「in 變量取值列表」可省略,省略時至關於in 「$@」,也就是使用for i 就至關於for i in 「$@」。mysql

說明:在for循環語句中,for關鍵字後面會有一個"變量名",變量名依次獲取in關鍵字後面的變量取值列表的內容(以空格分隔),每次僅取一個,而後進入循環執行循環中的全部指令,當執行到done時結束本次循環。以後變量在獲取變量列表裏的下一個變量值。繼續執行循環內的命令,當執行到done是結束返回,以此類推直到取完變量列表裏的最後一個值進入循環到done結束。linux

1.2 C語言型for循環結構

語法:git

for((exp1; exp2; exp3))

do

指令…

done

說明:for關鍵字後的括號內是三個表達式,第一個是變量初始化(例如:i=0),第二個是變量的取值範圍(例如:i<100),第三個爲變量的自增或自減(例如i++)。當第一個表達式的初始化的值符合第二個變量的範圍時,就進入循環執行;當條件不知足時就退出循環。web

for循環執行流程對應邏輯圖以下圖所示:sql

shell腳本編程學習之路-for循環

範例:while循環和for循環的對比shell

先看一下while循環語句數據庫

[root@shellbiancheng jiaobenlianxi]# cat while4.sh 
#!/bin/bash
i=1
while((i<=10))
do
    echo $i
    ((i++))
done

下面是for循環語句編程

[root@shellbiancheng jiaobenlianxi]# cat for1.sh 
#!/bin/bash

for((i=1;i<=10;i++))
do
    echo $i

done

說明:數組

(1)程序持續運行多用while,包括守護進程。

(2)有限次循環多用for,則多用for,實際工做中for運用的機會更多。

學習記憶的方法:

for 男人 in 全部男人

do

 if [ 有房 ] && [ 有車 ] && [ 存款 ] && [ 會作家務 ] && [ 帥氣 ] && [ 體貼 ] && [ 逛街買東西 ];then

echo 「女孩喜歡這樣的男人」

else

rm –f $男人

fi

done

1.3 for循環基礎案例

1.3.1 案例1:直接列出變量列表全部元素,打印1,2,3,4,5

方法1:

[root@shellbiancheng jiaobenlianxi]#  cat for3.sh 
for n in 1 2 3 4 5 

do
echo $n
done

方法2:使用大括號的方法

[root@shellbiancheng jiaobenlianxi]# cat for4.sh 
for n in {1..10}

do
echo 192.168.1.$n
done

方法3:使用seq生成隨機數的方法

[root@shellbiancheng jiaobenlianxi]# cat  for5.sh   
for n in  `seq 5 -1 1`   5是起始數字,-1表示每次減1,1是結束數字
do
echo $n
done

1.3.2 案例2:獲取當前目錄的文件名

[root@shellbiancheng jiaobenlianxi]# cat for5.sh 
for n in  `ls`
do
echo $n
done

1.3.3 案例3:隨機數生成文件

批量生成文件,文件名隨機md5處理後,選八位。

[root@shellbiancheng jiaobenlianxi]# cat suijiwnjian.sh 
for((i=1;i<=10;i++))
do
    mkdir -p ./test
    touch ./test/` echo $RANDOM|md5sum|cut -c 1-8`_finished.html
done
[root@shellbiancheng jiaobenlianxi]# ls test/
0ac2453a_finished.html  8b90c52b_finished.html  c4eb22c9_finished.html
2c1f5e87_finished.html  a22717d3_finished.html  db258218_finished.html
6d6bc69f_finished.html  a4aca3b0_finished.html
6d7c516a_finished.html  c21f3d55_finished.html

1.3.4 案例4:批量修改文件名

將上面生成的10個以.html結尾的文件修改爲以.jpg結尾。而且把finished去掉。

方法一:

[root@shellbiancheng jiaobenlianxi]# cat piliangxiugai1.sh 
for f in `ls test/*.html`
do
    mv $f `echo $f|sed 's#_finished.html#.jpg#g'`
done
[root@shellbiancheng jiaobenlianxi]# ls test/
0ac2453a.jpg  6d6bc69f.jpg  8b90c52b.jpg  a4aca3b0.jpg  c4eb22c9.jpg
2c1f5e87.jpg  6d7c516a.jpg  a22717d3.jpg  c21f3d55.jpg  db258218.jpg

方法二:for循環加變量部分截取的方法

[root@shellbiancheng jiaobenlianxi]# cat piliangxiugai3.sh 
for file in `ls test/*.html`
do
    /bin/mv $file "${file%_finished*}.jpg"
done

方法三:ls結合awk實現

[root@shellbiancheng test]# ls
0513d6f0_finished.html  6ab3573c_finished.html  8abfa660_finished.html
1a9335f3_finished.html  70018e1c_finished.html  bb6763ab_finished.html
559d16bc_finished.html  74e206b5_finished.html
58fc15d7_finished.html  7878f84a_finished.html
[root@shellbiancheng test]# ls |awk -F '[_]' '{print "mv " $0,$1".jpg"}'|bash

[root@shellbiancheng test]# ls
0513d6f0.jpg  559d16bc.jpg  6ab3573c.jpg  74e206b5.jpg  8abfa660.jpg
1a9335f3.jpg  58fc15d7.jpg  70018e1c.jpg  7878f84a.jpg  bb6763ab.jpg

方法四:經過rename實現

[root@shellbiancheng test]# ls
16d72ca3_finished.html  673c62da_finished.html  b9328787_finished.html
37690b31_finished.html  72ebc17d_finished.html  e37aeed5_finished.html
37e66161_finished.html  a5050e54_finished.html
4efe1f4c_finished.html  b2553039_finished.html
[root@shellbiancheng test]# rename "_finished.html" ".jpg" *
[root@shellbiancheng test]# ls
16d72ca3.jpg  37e66161.jpg  673c62da.jpg  a5050e54.jpg  b9328787.jpg
37690b31.jpg  4efe1f4c.jpg  72ebc17d.jpg  b2553039.jpg  e37aeed5.jpg

1.3.5 案例5:

實戰案例:開發腳本實現僅設置sshd crond rsyslog network 開機自啓動

[root@shellbiancheng jiaobenlianxi]# cat chkconfigoff.sh 
LANG=en
chkconfig --list|grep 3:on|awk '{print $1}' >b.log
for name in `chkconfig --list|grep 3:on|awk '{print $1}'|egrep -v "sshd|crond|rsyslog|network"`

do
  chkconfig $name off

done

[root@shellbiancheng jiaobenlianxi]# cat chkconfigon.sh 
LANG=en
for name in `cat b.log`
do
    chkconfig $name on
done

1.3.6 案例6:用for循環實現1-100之和

方法一:

[root@shellbiancheng jiaobenlianxi]# cat for1-100.sh 
for((i=1;i<=100;i++))
do
    let sum+=i
done
echo $sum
[root@shellbiancheng jiaobenlianxi]# sh for1-100.sh 
5050

方法二:

[root@shellbiancheng jiaobenlianxi]# cat for1-1000.sh 
for n in `seq 100`
do
    ((sum+=n))
done
echo $sum

方法三:

[root@shellbiancheng jiaobenlianxi]# cat for1-100_3.sh 
for n in `seq 100`
do
   a="$(($n*($n+1)/2))"
done
echo $a

1.3.7 案例7:實現mysql分庫備份

備份數據庫的命令爲:mysqldump -uroot -p123456 -S /data/3307/mysql.sock -B linzhongniao|gzip>/server/backup/linzhongniao_$(date +%F).sql.gz

腳本以下:

[root@mysql ~]# cat mysqlfenkubeifen.sh   
#!/bin/bash

export PATH="/usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"
DBPATH="/server/backup"
MYUSER="root"
MYPASS="123456"
SOCKET="/data/3307/mysql.sock"
MYCMD="mysql -u$MYUSER -P$MYPASS -S $SOCKET"
MYDUMP="mysqldump -u$MYUSER -p$MYPASS -S $SOCKET -B"

[ -d "$DBPATH" ] || mkdir -p $DBPATH

for dbname in `mysql -u$MYUSER -p$MYPASS -S $SOCKET -e "show databases;"|sed '1d'|egrep -v "mysql|schema"`

do

  $MYDUMP $dbname|gzip >$DBPATH/${dbname}_$(date +%F).sql.gz

done

執行結果以下:

[root@mysql ~]# ll /server/backup/
總用量 20
 -rw-r--r--. 1 root root 512 10月  4 19:32 dfhjdhf_2018-10-04.sql.gz
 -rw-r--r--. 1 root root 822 10月  4 19:32 linzhongniao_2018-10-04.sql.gz
 -rw-r--r--. 1 root root 507 10月  4 19:32 nn_2018-10-04.sql.gz
 -rw-r--r--. 1 root root 704 10月  4 19:32 school_2018-10-04.sql.gz
 -rw-r--r--. 1 root root 509 10月  4 19:32 test_2018-10-04.sql.gz

1.3.8 案例8:利用for循環批量建庫

[root@mysql jiaobenlianxi]# cat piliangjianku.sh  
#!/bin/bash
export PATH="/usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"
MYUSER="root"
MYPASS="123456"
SOCKET="/data/3307/mysql.sock"
MYCMD="mysql -u$MYUSER -p$MYPASS -S $SOCKET"
RETVAL=0
for dbname in `cat ./dbname.txt`
do

$MYCMD -e "use $dbname;" &>/dev/null
if [ $? -ne $RETVAL ];then
 $MYCMD -e "create database $dbname"
else
 echo "$dbname" >>./dbnamed.txt
fi
done

1.3.9 案例9:批量建立系統帳號並設置密碼

[root@mysql jiaobenlianxi]# cat user.sh
#!/bin/bash
#author=linzhongniao
#date:2018-10-04
#mail:xxxxxxx@163.com
#function:Batch create users and set password tests.
#version: 1.1

. /etc/init.d/functions
export PATH="/usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"
RETVAL=0
passfile="./user.log"
PASS="/etc/passwd"

[ -f "$passfile" ]|| touch $passfile
for user in `cat ./user.txt`

do
cat /etc/passwd|grep "$user"&>/dev/null
if [ $? -ne $RETVAL -a -w "$PASS" ];then
passwd="`echo "test$RANDOM"|md5sum|cut -c1-4`"
useradd $user &>/dev/null && echo "$user:$passwd">>$passfile
action "$user is OK."  /bin/true
else
action "$user is fail.The user has been created" /bin/false
fi
done
echo "------------------"
chpasswd < $passfile  #這個地方很關鍵讀取密碼文件對密碼進行設置必須是user:passwd這種格式
cat $passfile

2.linux系統產生隨機數的方法

方法一:用系統環境變量RANDOM來實現,示例代碼以下:

[root@shellbiancheng ~]# echo $RANDOM
11100
[root@shellbiancheng ~]# echo $RANDOM
24323
[root@shellbiancheng ~]# echo "linzhongniao$RANDOM"|md5sum|cut -c1-4
6e9b

RANDOM的隨機數範圍爲0-32767,務必記住,所以加密行不太好;能夠經過在輸出的隨機數前面增長加密字符串的方式來解決,最夠用md5sum加密取出想要的部分,這樣就不能根據隨機數結果猜出具體結果了。

方法二:使用expect附帶的mkpasswd生成隨機數

mkpasswd命令:mkpasswd——生成新的密碼,可選地將其應用於用戶;它依賴於數據包expect,所以必須經過「yum install expect -y」先安裝該數據包。

相關參數說明:

-l(小寫的L)(The -l flag defines the length of the password.  The default is 9.) 指定密碼的長度,默認長度是9。
 -d (The -d flag defines the minimum number of digits that must  be  in  the password. The default is 2.)指定密碼中數字的長度默認長度是2。
 -c (The -c flag defines the minimum number of lowercase alphabetic  charac-ters that must be in the password.  The default is 2.)指定密碼中小寫字母的數量,默認數量是2.
 -C(The  -C flag defines the minimum number of uppercase alphabetic charac-ters that must be in the password.  The default is 2.)指定密碼中大寫字母的數量,默認數量是2.
 -s(The -s flag defines the minimum number of special characters that  mustbe in the password.  The default is 1.)指定密碼中特殊符號的數量,默認是1.

示例代碼以下:

[root@shellbiancheng ~]# mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1
Z7vOlf|G8
[root@shellbiancheng ~]# mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1|md5sum|cut -c1-4
242a

3.select循環語句

select循環語句的主要做用可能就是建立菜單至關於用cat方法生成菜單,在執行帶select循環語句的腳本時輸出會按照數字順序的列表顯示一個菜單項,並顯示提示符(默認是#?),同時等待用戶輸入進行選擇。

語法結構以下:

select 變量名 in 菜單取值列表 

do 

    指令....

done

select循環結構執行流程邏輯圖以下圖所示:

shell腳本編程學習之路-for循環

與for循環不一樣的是,select循環執行後會出現菜單項供用戶選擇(不會自動循環全部變量列表),用戶只能輸入菜單項前面的數字序號,每輸入一次對應的數字序號就會執行一次循環,直到變量後面對應列表取完爲止。

3.1 select循環語句案例

案例一:用select循環打印簡單菜單項

方法1:

[root@shellbiancheng jiaobenlianxi]# cat select.sh 
#!/bin/bash
select name in linzhongniao zhangsan lisi xiangli
do
echo $name
done

執行結果以下:

[root@shellbiancheng jiaobenlianxi]# sh select.sh
1) linzhongniao
2) zhangsan
3) lisi
4) xiangli
#? 1        默認提示符是#?,後面會換掉
linzhongniao
#? 2
zhangsan
#? 3
lisi
#? 4
xiangli
#?

方法2:採用數組作變量

[root@shellbiancheng jiaobenlianxi]# cat select1.sh   
#!/bin/bash
array=(linzhongniao zhangsan lisi xiangli)
select name in "${array[@]}"
do
echo $name
done

案例二:調整select循環菜單項的默認提示符及利用select變量打印數字序號。

[root@shellbiancheng jiaobenlianxi]# cat select2.sh   
#!/bin/bash
PS3="Pls select a num fron menu:"  PS3就是控制select循環的提示符
array=(linzhongniao zhangsan lisi xiangli)
select name in "${array[@]}"
do
echo "$REPLY $name" $REPLY變量用於獲取菜單項對應的數字,也就是用戶輸入的數字
done

案例三:打印選擇菜單,一鍵安裝web服務

當用戶輸入1時,輸出「start installing lamp」而後執行/server/scripts/lamp.sh,腳本內容輸出「lamp is installed」後退出腳本;當用戶輸入2時,輸出「start installing lnmp」而後執行/server/script/lnmp.sh,輸出「lnmp is installed」後退出腳本;當輸入3時退出當前菜單及腳本。當輸入任何其餘字符,給出提示「Input error」後退出腳本。要對執行的腳本進行相關條件判斷,例如:腳本是否存在,是否可執行等。這個是第二種方法第一種用cat打印菜單。

[root@shellbiancheng ~]# cat webmenu2.sh  
#!/bin/bash
export PATH="/usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/curl/bin:/root/bin"
path="/server/scripts"
RETVAL=0
[ -d "$path" ]|| mkdir -p $path
function Usage(){
 echo $"Usage:you must input (1|2|3)"
}
function InstallService(){
if [ $# -ne 1 ];then
Usage
fi
local RETVAL=0
echo "start install ${1}"
sleep 2
if [ ! -x "$path/${1}.sh" ];then
echo "$path/lamp.sh does not exist or can not be exec."
else
source $path/lamp.sh
fi
}
function main(){
PS3="`echo pls input the num you want:`"
select var in "Install lamp" "Install lnmp" "exit"
do
case "$REPLY" in
1)
InstallService lamp
RETVAL=$?
;;
2)
InstallService lnmp
RETVAL=$?
;;
3)
echo bye.
return 3
;;
*)
echo "you must input (1|2|3)"
echo "input error"
;;
esac
done
exit $RETVAL
}
main
相關文章
相關標籤/搜索