語法:html
for 變量名 in 變量取值列表 do 指令… done
提示:在此結構中「in 變量取值列表」可省略,省略時至關於in 「$@」,也就是使用for i 就至關於for i in 「$@」。mysql
說明:在for循環語句中,for關鍵字後面會有一個"變量名",變量名依次獲取in關鍵字後面的變量取值列表的內容(以空格分隔),每次僅取一個,而後進入循環執行循環中的全部指令,當執行到done時結束本次循環。以後變量在獲取變量列表裏的下一個變量值。繼續執行循環內的命令,當執行到done是結束返回,以此類推直到取完變量列表裏的最後一個值進入循環到done結束。linux
語法:git
for((exp1; exp2; exp3)) do 指令… done
說明:for關鍵字後的括號內是三個表達式,第一個是變量初始化(例如:i=0),第二個是變量的取值範圍(例如:i<100),第三個爲變量的自增或自減(例如i++)。當第一個表達式的初始化的值符合第二個變量的範圍時,就進入循環執行;當條件不知足時就退出循環。web
for循環執行流程對應邏輯圖以下圖所示:sql
範例: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:
[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
[root@shellbiancheng jiaobenlianxi]# cat for5.sh for n in `ls` do echo $n done
批量生成文件,文件名隨機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
將上面生成的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
實戰案例:開發腳本實現僅設置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
方法一:
[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
備份數據庫的命令爲: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
[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
[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
方法一:用系統環境變量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
select循環語句的主要做用可能就是建立菜單至關於用cat方法生成菜單,在執行帶select循環語句的腳本時輸出會按照數字順序的列表顯示一個菜單項,並顯示提示符(默認是#?),同時等待用戶輸入進行選擇。
語法結構以下:
select 變量名 in 菜單取值列表 do 指令.... done
select循環結構執行流程邏輯圖以下圖所示:
與for循環不一樣的是,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