linux shell循環(huán):for、while、until用法詳解
學(xué)習(xí)腳本就是為了方便我們運維工作,而對運維人員從來講,有很多工作也是需要重復(fù)執(zhí)行的,比如我們管理用戶帳戶時就需要批量創(chuàng)建和刪除用戶帳戶。而此時如果使用系統(tǒng)自帶的useradd或者userdel去操作的話,就只能機械式的一個一個創(chuàng)建,一個一個的刪除。那我們是不是就可以考慮寫一個程序,讓它自動化的去創(chuàng)建了。此時,我們的循環(huán)執(zhí)行概念也就出來了。循環(huán)就是讓程序按照一定的條件反復(fù)的執(zhí)行相關(guān)操作,直到不在滿足循環(huán)條件時結(jié)束。
循環(huán)語句常見分類:
1,for語句
2,while語句
3,until語句
循環(huán)體包括兩部分:
1,循環(huán)的進入條件
2,循環(huán)的退出條件
循環(huán)次數(shù):
1,事先已知 for語句
2,事先未知 while、until語句
for循環(huán)常見語法格式:
for 變量名 in 列表;do
循環(huán)體
done
循環(huán)執(zhí)行機制:依次將列表中的元素賦值給變量名,每次賦值后執(zhí)行一次循環(huán)體,直到列表中的元素耗盡,循環(huán)結(jié)束
列表生成方式:
(1) 直接給出列表
(2) 整數(shù)列表:
(a) {start..end} 如:{1..10}
(b) $(seq [start [step]] end) 如:`seq 1 2 100` 表示1-100之間的所有奇數(shù)
(3) 返回列表的命令 $(COMMAND) 如:`ls /etc`
(4) 使用glob,如:*.sh
(5) 變量引用;$@, $*
for循環(huán)特殊用法:
雙小括號方法,即((…))格式,也可以用于算術(shù)運算
雙小括號方法也可以使bash Shell實現(xiàn)C語言風(fēng)格的變量操作
#I=10
#((I++))
for循環(huán)特殊用法格式:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式));do
循環(huán)體
done
控制變量初始化:僅在運行到循環(huán)代碼段時執(zhí)行一次控制變量的修正表達式:每輪循環(huán)結(jié)束會先進行控制變量修正運算,而后再做條件判斷for循環(huán)應(yīng)用實例:
1,計算1-100之間所有正整數(shù)的和
#!/bin/bash #Author:wangjun #Contact QQ:183530300 #Version:1.0 #Create time:2016-08-17 16:53:28 #Description:1-100 all positive integer's sum declare -i sum=0 for I in {1..100};do let sum+=$I done echo "1-100 all positive integer's sum : $sum"
2,自動掃描1-254網(wǎng)段的所有主機,統(tǒng)計在線主機數(shù)與不在線主機數(shù)
#!/bin/bash #Author:wangjun #Contact QQ:183530300 #Version:1.0 #Create time:2016-08-17 11:25:37 #Description:ping all hosts and count the number declare -i online=0 declare -i offline=0 declare -i host=1 for host in `seq 254`;do ping -c 1 -W 1 10.1.250.$host &> /dev/null && echo "10.1.250.$host is online" && let online=$online+1 || let offline++ done echo "Online hosts number : $online" echo "Offline hosts number : $offline"
3,生成10個隨機數(shù),并找出最大隨機數(shù)和最小隨機數(shù)
#!/bin/bash #Author:wangjun #Contact QQ:183530300 #Version:1.0 #Create time:2016-08-17 17:27:45 #Description:random number comparative minrandom=$RANDOM maxrandom=$minrandom echo $minrandom for I in {1..9};do RD=$RANDOM echo $RD if [[ $RD -gt $maxrandom ]];then maxrandom=$RD elif [[ $RD -lt $minrandom ]];then minrandom=$RD fi done echo "Minrandom is : $minrandom" echo "Maxrandom is : $maxrandom"
4,打印九九乘法表(第一版)
#!/bin/bash #Author:wangjun #Contact QQ:18353030 #Version:1.0 #Create time:2016-08-16 13:07:40 #Description:99 multiplication table for Row in {1..9};do for Column in `seq $Row`;do echo -ne "${Column}x${Row}=$[$Row*$Column]\t" done echo done
5,打印九九乘法表(第二版)——for循環(huán)特殊用法
#!/bin/bash #Author:wangjun #Contact QQ:183530300 #Version:1.0 #Create time:2016-08-18 11:35:16 #Description:multiplication table for ((row=1;row<=9;row++));do for ((column=1;column<=$row;column++));do echo -ne "${column}x${row}=$[${column}*${row}]\t" done echo done
循環(huán)執(zhí)行 :將某代碼段重復(fù)運行多次; 重復(fù)運行多少次: 循環(huán)次數(shù)事先已知 ;循環(huán)次數(shù)事先未知 ;有進入條件和退出條件。
三種循環(huán)體:for、while、until。
再循環(huán)前前介紹步進,在循環(huán)中經(jīng)常用到步進。
步進
顯示1-10
[root@centos6mini app]# echo {1..10} 1 2 3 4 5 6 7 8 9 10 [root@centos6mini app]# echo $(seq 1 10) 1 2 3 4 5 6 7 8 9 10
1-10 遞加
[root@centos6mini app]# echo {1..10..2}
1 3 5 7 9
[root@centos6mini app]# echo $(seq 1 2 10)
1 3 5 7 9
1-10 遞減
[root@centos6mini app]# echo {10..1..2}
10 8 6 4 2
[root@centos6mini app]# echo $(seq 10 -2 1)
10 8 6 4 2
1-100間的奇數(shù)和偶數(shù)
[root@centos6mini app]# echo {1..100..2}
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99
[root@centos6mini app]# echo {2..100..2}
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100
[root@centos6mini app]# echo {100..1..2}
100 98 96 94 92 90 88 86 84 82 80 78 76 74 72 70 68 66 64 62 60 58 56 54 52 50 48 46 44 42 40 38 36 34 32 30 28 26 24 22 20 18 16 14 12 10 8 6 4 2
[root@centos6mini app]# echo {99..1..2}
99 97 95 93 91 89 87 85 83 81 79 77 75 73 71 69 67 65 63 61 59 57 55 53 51 49 47 45 43 41 39 37 35 33 31 29 27 25 23 21 19 17 15 13 11 9 7 5 3 1
隨機生成16位包含數(shù)字、大小寫字母、符號的密碼
cat /dev/urandom |tr -dc '0-9a-zA-Z!@_#?.,' |head -c 16
tr -d 和 tr -dc 的用法
[root@centos6mini app]# echo 12324345 |tr -d 2 #不要數(shù)字2
134345
[root@centos6mini app]# echo 12324345 |tr -dc 2 #支取數(shù)字2
22
for循環(huán)
for 變量名 in 列表;do
循環(huán)體
done
執(zhí)行機制:
依次將列表中的元素賦值給“變量名”; 每次賦值后即執(zhí) 行一次循環(huán)體; 直到列表中的元素耗盡,循環(huán)結(jié)束
for循環(huán)的列表生成方式:
(1) 直接給出列表
(2) 整數(shù)列表:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 返回列表的命令 $(COMMAND)
(4) 使用glob,如:*.sh
(5) 變量引用; $@, $*
批量創(chuàng)建user1至user10,要求設(shè)置隨機16位密碼,包含數(shù)字、大小寫字母、符號。并要求用戶使用密碼首次登錄后,強制設(shè)置新密碼。
#!/bin/bash > /root/user.log for i in {1..10};do #創(chuàng)建十個用戶 useradd user$i && echo user$i is created #隨機生成密碼 password=$(cat /dev/urandom |tr -dc '0-9a-zA-Z!@_#?.,' |head -c 16) #將用戶和密碼導(dǎo)出 echo user$i:$password >> /root/user.log #設(shè)置密碼 echo $password |passwd --stdin user$i &> /dev/null #強制下次登錄修改密碼 passwd -e user$i &> /dev/null done
使用♥,利用for,顯示出一個等腰三角形。
方法一:
for ((i=1;i<10;i++)) do for ((j=1;j<=i;j++)) do echo -n "♥" done echo done for ((i=1;i<9;i++)) do for ((j=9;j>i;j--)) do echo -n "♥" done echo done ♥ ♥♥ ♥♥♥ ♥♥♥♥ ♥♥♥♥♥ ♥♥♥♥♥♥ ♥♥♥♥♥♥♥ ♥♥♥♥♥♥♥♥ ♥♥♥♥♥♥♥♥♥ ♥♥♥♥♥♥♥♥ ♥♥♥♥♥♥♥ ♥♥♥♥♥♥ ♥♥♥♥♥ ♥♥♥♥ ♥♥♥ ♥♥ ♥
方法二:
#!/bin/bash2 read -p "請輸入三角形的高度: " num for i in `seq $num`;do for x in `seq 1 $[$num-$i]`;do echo -e " \c" done for n in `seq 1 $[2*$i-1]`;do #yanse=`tr -dc '1-6' < /dev/urandom | head -c 1` #echo -e "\e[3"$yanse"m♥\e[0m\c" echo -e "\e[34m♥\e[0m\c" done echo done ♥ ♥♥♥ ♥♥♥♥♥ ♥♥♥♥♥♥♥
方法三:
#!/bin/bash for ((i = 1; i < 10; i++)) do for ((j = 10; j > i; j--)) do echo -n " "; done for ((m = 1; m <= i; m++)) do echo -n "$i " done echo "" done [root@centos7 ~]# ./sjx 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9
方法四:
#!/bin/bash #彩色閃爍山角形 read -p "請輸入三角形邊長: " w for (( i=1;i<=$w;i++ )); do for(( j=$w;j>$i;j-- ));do echo -n " " done for (( m=1;m<=i;m++ ));do we=`cat /dev/urandom |tr -dc '1-6' |head -c 1 ` echo -e "\033[3"$we";5m♥\033[0m\c" #紅色加閃爍 done echo done
添加10個用戶user1-user10,密碼為8位隨機字符、
#!/bin/bash > /root/user.log for i in {1..10};do useradd user$i && echo user$i is created pass=$(cat /dev/urandom |tr -dc '0-9a-zA-Z!@_#?.,' |head -c 16) #生成隨機數(shù) echo user$i:---pass:$pass >> /root/user.log echo $pass |password --stdin user$i &> /dev/null done
/etc/rc.d/rc3.d目錄下分別有多個以K開頭和以S開頭的文件;分別讀取每個文件,以K開頭的輸出為文件加stop,以S開頭的輸出為文件名加start,如K34filename stop S66filename start
#!/bin/bash for i in $(ls /etc/rc.d/rc3.d/);do #查看文件內(nèi)容確定循環(huán)次數(shù) if [[ $i =~ ^K.* ]];then echo "$i stop" elif [[ $i =~ ^S.* ]];then echo "$i start" fi done [root@centos6mini app]# ./linshi K05wdaemon stop K10saslauthd stop K15htcacheclean stop K15httpd stop K30spice-vdagentd stop K50dnsmasq stop K50kdump stop K73winbind stop K74ntpd stop ...省略...
編寫腳本,提示輸入正整數(shù)n的值,計算1+2+…+n的總和
#!/bin/bash read -p "請輸入一個正整數(shù)" s w=0 if [[ "$s" =~ ^[0-9]+$ ]] ;then for i in $(seq 1 $s) ;do w=$[$w+$i] done echo "整數(shù)1到$s的和為$w" else echo "請輸入正整數(shù)" fi
計算100以內(nèi)所有能被3整除的整數(shù)之和
方法一:
[root@centos6mini app]# echo {3..100..3} |tr " " "+"|bc #進行步進,替換相加
1683
方法二:
#!/bin/bash for i in {3..100..3};do #步進,相加 n=$[$n+$i] &> /devnull done echo $n
方法三:
#!/bin/bash sum=0 for n in $(seq 1 100);do i=$[$n/3] #進行相除 y=$[3*$i] #進行相乘 、運算成功則成立 if [ $y -eq $n ];then sum=$[$n+$sum] fi done echo $sum
方法四:
sum=0 for i in {1..100};do if [ $[$i%3] -eq 0 ];then #相除取余進行判定 let sum+=$i #進行加法運算 fi done echo $sum
打印九九乘法表
for (( i=1 ;i<=9;i++ ));do for ((n=1;n<=9;n++)) ;do w=0 w=$[$n*$i] if [ $n -le $i ];then echo -n " $i*$n=$w " fi done echo done
在/testdir目錄下創(chuàng)建10個html文件,文件名格式為數(shù)字N(從1到10)加隨機8個字母,如:1AbCdeFgH.html
方法一:
#!/bin/bash cd /testdir &> /dev/null if [ ! $(echo $?) -eq 0 ] ;then #判斷文件是否存在 mkdir /testdir &> /dev/null fi for i in $(seq 1 10 );do w=$(cat /dev/urandom |tr -dc '0-9a-zA-Z!@_#?.,' |head -c 8) touch $i$w.html done
方法二:
if ! [ -d /testdir ];then #判斷文件是否存在 mkdir /testdir &> /dev/null #如果沒有創(chuàng)建文件 fi for i in {1..10};do touch /testdir/$i`cat /dev/urandom |tr -dc [:alpha:] |head -c 8`.html #創(chuàng)建文件 done
探測局域網(wǎng)內(nèi)的主機
172.18.250-254.X
能ping通顯示并保存至/root/ip.log
要求并行探測提高效率。
[root@centos6mini zuoye]# cat 11.sh #!/bin/bash > /root/ip.log for i in {250..255};do for n in {1..255};do { ping -c1 -w1 172.18."$i"."$n" &> /dev/null if [ $? -eq 0 ] ;then echo "ping 172.18."$i"."$n" is up" #>> /root/ip.log fi }& done done [root@centos6mini zuoye]# ./11.sh ping 172.18.250.14 is up ping 172.18.250.26 is up ping 172.18.250.71 is up ping 172.18.250.81 is up ping 172.18.250.112 is up ping 172.18.250.154 is up ping 172.18.250.164 is up ping 172.18.250.166 is up ping 172.18.250.183 is up ping 172.18.250.195 is up ping 172.18.250.212 is up ping 172.18.250.216 is up ping 172.18.250.224 is up ping 172.18.250.249 is up ping 172.18.250.250 is up ping 172.18.251.18 is up
打印國際象棋棋盤
方法一:
[root@centos6mini zuoye]# cat qipan.sh #!/bin/bash for n in {1..8};do for i in {1..8} ;do if [ $[$n%2] -eq 0 ];then if [ $[$i%2] -eq 0 ];then echo -e "\033[41m \033[0m\c" fi if [ $[$i%2] -ne 0 ] ;then echo -e "\033[47m \033[0m\c" fi else if [ $[$i%2] -eq 0 ];then echo -e "\033[47m \033[0m\c" fi if [ $[$i%2] -ne 0 ] ;then echo -e "\033[41m \033[0m\c" fi fi done echo done
方法二:
#!/bin/bash for xline in $(seq 1 8);do #橫向 for yline in $(seq 1 8);do #縱向 if [ $[$[$xline+$yline]%2] -eq 0 ];then #判斷;橫向與縱向相加,最后相除是否等于0 echo -e "\033[47m \033[0m\c" else echo -e "\033[41m \033[0m\c" fi done echo done
方法三:(放大版)
#!/bin/bash for i in {1..8};do for x in {1..4};do #控制單行大小。對已有輸出進行放大 for n in {1..8};do a=`echo $[$[$i+$n]%2]` if [ $a -eq 0 ];then echo -e "\e[43m" "" "" "" "" "" "" "" "\e[0m\c" else echo -e "\e[42m" "" "" "" "" "" "" "" "\e[0m\c" fi done echo done done
while循環(huán)
while CONDITION; do
循環(huán)體
done
CONDITION:循環(huán)控制條件;進入循環(huán)之前,先做一次判 斷;每一次循環(huán)之后會再次做判斷;條件為“true”,則執(zhí)行 一次循環(huán);直到條件測試狀態(tài)為“false”終止循環(huán)
因此:CONDTION一般應(yīng)該有循環(huán)控制變量;而此變量的值 會在循環(huán)體不斷地被修正
進入條件:CONDITION為true
退出條件:CONDITION為false
“:” 和true的返回值都為真
[root@centos6mini zuoye]# true
[root@centos6mini zuoye]# echo $?
0
[root@centos6mini zuoye]# :
[root@centos6mini zuoye]# echo $?
0
判斷/var/目錄下所有文件的類型
[root@centos6mini app]# cat linshi #!/bin/bash dc=0 lc=0 cc=0 bc=0 oc=0 zc=0 ls -l /var |grep -v total >/tmp/var_ftype.txt while read lines do ftype=`echo $lines |awk '{print $1}' |cut -c 1` case $ftype in d) dname=`echo $lines |awk '{print $9}'`; echo "$dname is a Directory" ; let dc+=1;; l) lname=`echo $lines |awk '{print $9}'`; echo "$lname is a Links of Soft " ;let lc+=1 ;; c) cname=`echo $lines |awk '{print $9}'`; echo "$cname is a Character of file" ;let cc+=1;; b) bname=`echo $lines |awk '{print $9}'`; echo "$bname is a Block file" ; let bc+=1;; -) zname=`echo $lines |awk '{print $9}'`; echo "$zname is a common file" ; let zc+=1;; *) echo "Others files"; let oc+=1 esac done </tmp/var_ftype.txt echo '-----------------------------' echo -e "var目錄下普通文件數(shù)量: $zc\nvar目錄下子目錄數(shù)量:$dc\nvar目錄下鏈接文件數(shù)量:$lc\nvar目錄下字符類型文件數(shù)量: $cc\nvar 目錄下塊設(shè)備文件數(shù)量:$bc\n其他類型文件數(shù)量:$oc" rm -f /tmp/var_ftype.txt [root@centos6mini app]# ./linshi cache is a Directory crash is a Directory cvs is a Directory db is a Directory empty is a Directory games is a Directory gdm is a Directory lib is a Directory local is a Directory lock is a Directory log is a Directory mail is a Links of Soft nis is a Directory opt is a Directory preserve is a Directory run is a Directory spool is a Directory tmp is a Directory www is a Directory yp is a Directory ----------------------------- var目錄下普通文件數(shù)量: 0 var目錄下子目錄數(shù)量:19 var目錄下鏈接文件數(shù)量:1 var目錄下字符類型文件數(shù)量: 0 var 目錄下塊設(shè)備文件數(shù)量:0 其他類型文件數(shù)量:0
編寫腳本,求100以內(nèi)所有正奇數(shù)之和
方法一:
[root@centos6mini zuoye]# echo {1..100..2} 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 [root@centos6mini zuoye]# echo {1..100..2}|tr " " + |bc 2500
方法二:
[root@centos6mini 3.19]# ./1 2500 [root@centos6mini 3.19]# cat 1 #!/bin/bash u=0 for i in {1..100..2}; do let u+=i done echo $u
方法三:
[root@centos6mini 3.19]# ./1 2500 [root@centos6mini 3.19]# cat 1 #!/bin/bash u=0 i=1 while [ $i -le 100 ] ;do let u+=i let i+=2 done echo $u
編寫腳本,提示請輸入網(wǎng)絡(luò)地址,如192.168.0.0,判斷輸入的網(wǎng)段中主機在線狀態(tài),并統(tǒng)計在線和離線主機各多少
方式一:
#!/bin/bash w=0 a=0 y=0 for (( d=0;d<256;d++ ));do for (( f=1;f<255;f++ ));do { ping -c1 -w1 172.18."$d"."$f" &> /dev/null a=`echo $?` if [ $a -eq 0 ] ; then echo "172.18."$d"."$f" up" >> /app/e.txt echo "172.18."$d"."$f" up " fi if [ $a -ne 0 ] ; then echo "172.18."$d"."$f" down " >> /app/r.txt echo "172.18."$d"."$f" down " fi }& done done w=`cat /app/e.txt |wc -l` echo "通的 : $w" y=`cat /app/r.txt |wc -l` echo "不通的 : $y" rm -rf /app/e.txt rm -rf /app/w.txt
方式二:
#!/bin/bash i=1 q=1 w=0 a=0 y=0 while [ $i -lt 255 ];do while [ $q -lt 255 ];do { ping -c1 -w1 172.18."$i"."$q" &> /dev/null a=`echo $?` if [ $a -eq 0 ] ; then echo "172.18."$i"."$q" up" >> /app/e.txt echo "172.18."$i"."$q" :up" fi if [ $a -ne 0 ] ; then echo "172.18."$i"."$q" down " >> /app/w.txt echo "172.18."$i"."$q" down " fi }& let q=q+1 done let i=i+1 q=1 ####將q的變量值從新賦值為1 done w=`cat /app/e.txt |wc -l` echo "通的主機數(shù)為 : $w" y=`cat /app/w.txt |wc -l` echo "不通的主機數(shù)為 : $y" rm -rf /app/w.txt /app/e.txt
編寫腳本,打印九九乘法表
[root@centos6mini 3.19]# cat 99 #!/bin/bash q=1 w=1 while [ $q -le 9 ];do while [ $w -le 9 ];do e=0 let e=q*w if [ $w -le $q ];then echo -n " $w*$q=$e " fi let w+=1 done let q+=1 w=1 echo done [root@centos6mini 3.19]# ./99 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
4、編寫腳本,利用變量RANDOM生成10個隨機數(shù)字,輸出這個10數(shù)字,并顯示其中的最大值和最小值
[root@centos6mini 3.19]# ./4 25955 25748 16113 19729 8944 19049 16202 20067 30609 4309 最大值: 30609 最小值: 4309 [root@centos6mini 3.19]# cat 4 #!/bin/bash q=1 while [ $q -le 10 ] ;do echo $[RANDOM] &>> /app/o.txt #echo $[RAND0M] #每次隨機都是新的值 let q+=1 done cat /app/o.txt w=`cat /app/o.txt |sort -rn |tail -n1` e=`cat /app/o.txt |sort -rn | head -n 1` echo "最大值: $e" echo "最小值: $w" rm -rf /app/o.txt
5、編寫腳本,實現(xiàn)打印國際象棋棋盤[
[root@centos6mini 3.19]# cat 5,sh #!/bin/bash q=1 w=1 while [ $q -le 8 ] ;do while [ $w -le 8 ] ;do if [ $[$[$q+$w]%2] -eq 0 ] ;then ##判斷句中的計算需要$[]括起來: echo -e "\033[47m \033[0m\c" else echo -e "\033[41m \033[0m\c" fi let w+=1 done let q+=1 w=1 echo done
后續(xù)六個字符串:efbaf275cd、4be9c40b8b、44b2395c46、f8c8873ce0、b902c16c8b、ad865d2f63是通過對隨機數(shù)變量RANDOM隨機執(zhí)行命令:
echo $RANDOM|md5sum|cut –c1-10
后的結(jié)果,請破解這些字符串對應(yīng)的RANDOM值
方法一:
#!/bin/bash >6 while true ;do while true ;do w=`echo $RANDOM ` #定義變量--隨機數(shù)隨時在變化,給他賦值一個變量,后邊取值就不在變化了 q=`echo $w|md5sum|cut -c1-10` if [ $q == efbaf275cd ] ;then echo "efbaf275cd=$w" #>>6 elif [ $q == 4be9c40b8b ] ;then echo "4be9c40b8b=$w" #>>6 elif [ $q == 44b2395c46 ] ;then echo "44b2395c46=$w" #>>6 elif [ $q == f8c8873ce0 ] ;then echo "f8c8873ce0=$w" #>>6 elif [ $q == b902c16c8b ] ;then echo "b902c16c8b=$w" #>>6 elif [ $q == ad865d2f63 ] ;then echo "ad865d2f63=$w" #>>6 fi done done [root@centos6mini ~]# cat 6 |sort|uniq 44b2395c46=9000 4be9c40b8b=12000 ad865d2f63=1000 b902c16c8b=3000 efbaf275cd=15000 f8c8873ce0=6000
方法二:
#!/bin/bash sum=0 for i in {1..32767};do num=`echo $i |md5sum | cut -c1-10` case $num in efbaf275cd|4be9c40b8b|44b2395c46|f8c8873ce0|b902c16c8b|ad865d2f63) echo $i let sum++ ;; esac if [ $sum -lt 6 ];then continue else break fi done
$#和$*差別
[root@centos6mini 3.19]# ./linshi 1 2 2 3 4 1 2 2 3 4 2 2 3 4 2 3 4 3 4 4 [root@centos6mini 3.19]# cat linshi #!/bin/bash while [ $# -gt 0 ];do echo $* shift done [root@centos6mini 3.19]# ./linshi 1 2 2 3 4 5 4 3 2 1 [root@centos6mini 3.19]# cat linshi #!/bin/bash while [ $# -gt 0 ];do echo $# shift done
使用一條命令,依次創(chuàng)建指定的用戶。如執(zhí)行createuser.sh tom bob alice harry
方法1:
[root@centos6mini 3.19]# ./linshi createuser.sh tom bob alice harry createuser.sh 用戶創(chuàng)建成功 tom 用戶創(chuàng)建成功 bob 用戶創(chuàng)建成功 alice 用戶創(chuàng)建成功 harry 用戶創(chuàng)建成功 [root@centos6mini 3.19]# cat linshi #!/bin/bash #!/bin/bash while [ $# -gt 0 ] do id $1 &>/dev/null if [ $? -eq 0 ];then echo $1 is already exsit. shift continue fi useradd $1 echo "$1 用戶創(chuàng)建成功" shift done 刪除用戶 [root@centos6mini 3.19]# ./linshi createuser.sh tom bob alice harry createuser.sh 用戶刪除成功 tom 用戶刪除成功 bob 用戶刪除成功 alice 用戶刪除成功 harry 用戶刪除成功 [root@centos6mini 3.19]# cat linshi #!/bin/bash while [ $# -gt 0 ];do userdel -r $1 echo "$1 用戶刪除成功" shift done
方法2:
#!/bin/bash while [ $# -gt 0 ];do id $1 &> /dev/null && { echo $1 is alread exist && shift && continue; } useradd $1 && echo $1 is created shift done
每隔3秒鐘到系統(tǒng)上獲取已經(jīng)登錄的用戶的信息;如果發(fā)現(xiàn)用戶hacker登錄,則將登錄時間和主機記錄于日志/var/log/login.log中,并退出腳本
#!/bin/bash while true;do if $(ps -au |grep "^hacker.*" &> /dev/null);then #監(jiān)測前臺終端上有沒有用戶登陸信息 echo $(ps -au |grep "^hacker.*" |tr -s " " |cut -d" " -f1,7,9) >> /var/log/login.log #將用戶登陸信息保存到日志文件中/var/log/login.log break #推出監(jiān)測 else sleep 3s #三秒已監(jiān)測,防止程序太多占用cpu fi done
隨機生成10以內(nèi)的數(shù)字,實現(xiàn)猜字游戲,提示比較大或小,相等則退出
[root@centos6mini 3.19]# ./linshi 請輸入數(shù)值 : 1 錯了 ,小了 請輸入數(shù)值 : 9 錯誤,大了 請輸入數(shù)值 : 5 猜對了 [root@centos6mini 3.19]# cat linshi #!/bin/bash qe=$( echo $[$RANDOM%10] ) while true ;do read -p "請輸入數(shù)值 : " qw if [ $qw -gt $qe ] ;then echo "錯誤,大了" elif [ $qw -lt $qe ] ;then echo "錯了 ,小了" elif [ $qe -eq $qw ];then echo "猜對了" break fi done
用文件名做為參數(shù),統(tǒng)計所有參數(shù)文件的總行數(shù)
[root@centos6mini 3.19]# ./linshi /etc/passwd /etc/sysconfig/network-scripts/ifcfg-eth1 /etc/passwd 89 [root@centos6mini 3.19]# cat linshi #!/bin/bash sumhang=0 while [ $# -gt 0 ];do hang=$( cat $1 | wc -l ) let sumhang+=hang shift done echo $sumhang
4、用二個以上的數(shù)字為參數(shù),顯示其中的最大值和最小值
方法一:
#!/bin/bash min=$1 #最小值等于第一個數(shù)值 max=$1 #最大數(shù)等于第一個數(shù)值 while [ $# -gt 0 ];do #進行數(shù)值數(shù)量進行判斷,做循環(huán) value=$1 #定義變量 if [ $value -gt $max ];then #當(dāng)?shù)诙€數(shù)大于第一個數(shù)時 max=$value #最大值等于后一個數(shù)值,對max從新賦與新的值 elif [ $value -lt $min ];then #當(dāng)?shù)诙€數(shù)大于第一個數(shù)時 min=$value #最小值等于后一個數(shù)值 對min從新賦與新的值 fi shift #不管前面判斷是否成立,都進行數(shù)列左移, done echo "min $min" echo "max $max"
方法二:
#!/bin/bash if [ $# -lt 2 ];then #對輸入數(shù)字數(shù)量進行檢測 echo "type more than two numbers" exit 1 fi small=$(echo $* |xargs -n1 |sort -n |head -n 1) #進行數(shù)值排序 big=$(echo $* |xargs -n1 |sort -n |tail -n 1) echo "Maximum number is $big" echo "Minimum number is $small" [root@localhost ~]# echo 1 -3 -99 46 7 32 43 2133 312 |xargs -n1 #以一數(shù)列進行顯示 1 -3 -99 46 7 32 43 2133 312
read 示例:
[root@centos6mini 3.19]# while read -p "type your name: " name ;do echo your is $n$name; done type your name: zhangsan your is zhangsan type your name: lisi your is lisi type your name: wangwu your is wangwu type your name: ^C [root@centos6mini 3.19]# read bing < test。txt [root@centos6mini 3.19]# echo $bing hello ^C [root@centos6mini 3.19]# while read name ; do echo $name ;done # 沒有指定輸入 123 #輸入 123 #輸出 qwe #輸入 qwe #輸出 asd #輸入 asd #輸出 zxc #輸入 zxc #輸出 ^C^[[A^C [root@centos6mini 3.19]# while read name ; do echo $name ;done <6 #name為變量,輸入來自文件文件內(nèi)容讀取完了,循環(huán)停止 hello qweqew 12341234 asdas ads sda sad asd as asd as
read 示例:
顯示UID小于1000的為sys user,大于等于1000的為comm user。
[root@centos6mini 3.19]# cat linshi #!/bin/bash while read usline ;do #通過read ,定義變量值usline usuid=$( echo $usline |cut -d: -f3 ) ,#引用變量usline ,并定義變量usuid usname=$( echo $usline |cut -d: -f1 ) #引用變量usline ,并定義變量usname #if [ $usuid -lt 1000 ];then #進行判斷 if (( $usuid < 1000 )) ;then #進行判斷(兩種方式均可以) echo "$usname is a sys user" else echo "$usname is a comm user" fi done < /etc/passwd #每次循環(huán)引用文件內(nèi)容一行,進行操作,引用完了,循環(huán)停止。 [root@centos6mini 3.19]# ./linshi root is a sys user bin is a sys user daemon is a sys user adm is a sys user lp is a sys user sync is a sys user shutdown is a sys user halt is a sys user mail is a sys user uucp is a sys user operator is a sys user games is a sys user gopher is a sys user ftp is a sys user nobody is a sys user vcsa is a sys user saslauth is a sys user
找出分區(qū)利用率大于10%的分區(qū),并發(fā)出警告/dev/sdaX will be full: 15%要求使用while read來實現(xiàn)
答案1:
#!/bin/bash df |grep /dev/sd > /app/fenqu while read line;do used=$(echo $line |tr -s " " % |cut -d% -f5) name=$(echo $line |cut -d" " -f1) if (( $used > 10 ));then echo "$name will be full:$used%" fi done < /app/fenqu [root@centos6mini 3.19]# df |grep /dev/sd >/app/zuoye/3.19/6 [root@centos6mini 3.19]# cat /app/zuoye/3.19/6 /dev/sda5 28564480 1872060 25234756 7% / /dev/sda2 20511356 70276 19392504 1% /app /dev/sda1 194241 31785 152216 18% /boot [root@centos6mini 3.19]# while read line ;do > used=$(echo $line |tr -s " " % |cut -d% -f5) > name=$(echo $line |cut -d" " -f1) > if (( $used > 10 ));then > echo "$name will be full:$used%" > fi > done </app/zuoye/3.19/6 /dev/sda1 will be full:18%
答案2:
#!/bin/bash > df_h df -h | grep ^/dev/[sh]d* >> df_h while read disk;do a=`echo $disk |grep -o "\<[0-9]\{0,3\}%" | cut -d% -f1` b=`echo $disk |grep -o "^[^[:space:]]\+\>"` if [ $a -gt 10 ];then echo "$b will be full: $a%" fi done < df_h
答案3:sed實現(xiàn)
#!/bin/bash df |grep /dev/sd |while read disk;do diskused=$(echo $disk |sed -r 's/.* ([0-9]+)%.*/\1/') diskname=$(echo $disk |sed -r 's@(/dev/sd[[:lower:]][[:digit:]]).*@\1@') if (( $diskused > 10 ));then echo "$diskname will be full:$diskused%" fi done
until循環(huán)
until CONDITION; do
循環(huán)體
done
進入條件: CONDITION 為false
退出條件: CONDITION 為true
循環(huán)控制語句continue
用于循環(huán)體中
continue [N]:提前結(jié)束第N層的本輪循環(huán),而直接進入下一 輪判斷;最內(nèi)層為第1層
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
continue
fi
CMDn
循環(huán)控制語句break
用于循環(huán)體中
break [N]:提前結(jié)束第N層循環(huán),最內(nèi)層為第1層
while CONDTIITON1; do CMD1 ... if CONDITION2; then break fi CMDn ... done
循環(huán)控制shift命令
shift [n]
用于將參量列表 list 左移指定次數(shù),缺省為左移一次。
參量列表 list 一旦被移動,最左端的那個參數(shù)就從列表中刪 除。while 循環(huán)遍歷位置參量列表時,常用到 shift
./doit.sh a b c d e f g h
./shfit.sh a b c d e f g h
特殊用法
1、while循環(huán)的特殊用法(遍歷文件的每一行):
while read line; do
循環(huán)體
done < /PATH/FROM/SOMEFILE
依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將 行賦值給變量line
2、雙小括號方法,即((…))格式,也可以用于算術(shù)運算
雙小括號方法也可以使bash Shell實現(xiàn)C語言風(fēng)格的變量操作
I=10
((I++))
for循環(huán)的特殊格式: for ((控制變量初始化;條件判斷表達式;控制變量的修正表達 式))
do
循環(huán)體
done
控制變量初始化:僅在運行到循環(huán)代碼段時執(zhí)行一次
控制變量的修正表達式:每輪循環(huán)結(jié)束會先進行控制變量修 正運算,而后再做條件判斷
select循環(huán)與菜單
select variable in list
do
循環(huán)體命令
done
select 循環(huán)主要用于創(chuàng)建菜單,按數(shù)字順序排列的 菜單項將顯示在標準錯誤上,并顯示 PS3 提示符, 等待用戶輸入
用戶輸入菜單列表中的某個數(shù)字,執(zhí)行相應(yīng)的命令
用戶輸入被保存在內(nèi)置變量 REPLY 中
select與case
select 是個無限循環(huán),因此要記住用 break 命令退 出循環(huán),或用 exit 命令終止腳本。也可以按 ctrl+c 退出循環(huán)
select 經(jīng)常和 case 聯(lián)合使用
與 for 循環(huán)類似,可以省略 in list,此時使用位置 參量
信號捕捉trap
trap '觸發(fā)指令' 信號
自定義進程收到系統(tǒng)發(fā)出的指定信號后,將執(zhí)行觸發(fā)指令 ,而不會執(zhí)行原操作
trap '' 信號
忽略信號的操作
trap '-' 信號
恢復(fù)原信號的操作
trap -p
列出自定義信號操作
文件測試
-z string 測試指定字符是否為空,空著真,非空為假
-n string 測試指定字符串是否為不空,空為假 非空為真 -e FILE 測試文件是否存在 -f file 測試文件是否為普通文件 -d file 測試指定路徑是否為目錄
-r file 測試文件對當(dāng)前用戶是否可讀
-w file 測試文件對當(dāng)前用戶是否可寫
-x file 測試文件對當(dāng)前用戶是都可執(zhí)行
-z 是否為空 為空則為真 -a 是否不空
-u file :是否存在且擁有suid權(quán)限
-g file :是否存在且擁有sgid權(quán)限
-k file :是否存在且擁有sticky權(quán)限
[root@centos6mini 3.19]# [ -n "" ]&& echo true #空為假
[root@centos6mini 3.19]# [ -n "1" ]&& echo true #非空為真
true
[root@centos6mini 3.19]# [ -n " " ]&& echo true #非空為真
true
[root@centos6mini 3.19]# [ -n ]&& echo true #非空為真
true
[root@centos6mini 3.19]# [ -z ]&& echo true #空為真
true
[root@centos6mini 3.19]# [ -z "" ]&&echo true #空為真
true
[root@centos6mini 3.19]# [ -z "1" ] && echo true "#非空為假
[root@centos6mini 3.19]# [ -z " " ] && echo true #非空為假
掃描/etc/passwd文件每一行,如發(fā)現(xiàn)GECOS字段為空,則填充用戶名和單位電話為62985600,并提示該用戶的GECOS信息修改成功。
#!/bin/bash cat /etc/passwd |while read userline;do #用管道實現(xiàn)給循環(huán)while賦值 if [ -n "$(echo $userline |cut -d: -f5)" ];then #-n "1" 非空為真 continue #為真時啥都不做 else username=$(echo $userline|cut -d: -f1) usermod -c $username-62985600 $username echo $username\'s gecos already changed! fi done
特殊用法
雙小括號方法,即((…))格式,也可以用于算術(shù)運算
雙小括號方法也可以使bash Shell實現(xiàn)C語言風(fēng)格的變量操作
I=10
((I++))
for循環(huán)的特殊格式:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達 式))
do
循環(huán)體
done
控制變量初始化:僅在運行到循環(huán)代碼段時執(zhí)行一次
控制變量的修正表達式:每輪循環(huán)結(jié)束會先進行控制變量修 正運算,而后再做條件判斷
練習(xí):計算從1加到100的和。
#!/bin/bash sum=0 for ((i=1;i<=100;i++));do let sum+=i done echo sum=$sum unset sum i sum=0 i=1 while [ $i -le 100 ];do let sum+=i let i++ done echo sum=$sum
select循環(huán)與菜單
select variable in list
do
循環(huán)體命令
done
select 循環(huán)主要用于創(chuàng)建菜單,按數(shù)字順序排列的 菜單項將顯示在標準錯誤上,并顯示 PS3 提示符, 等待用戶輸入
PS3="Please choose your menu: "
用戶輸入菜單列表中的某個數(shù)字,執(zhí)行相應(yīng)的命令
用戶輸入被保存在內(nèi)置變量 REPLY 中
[root@centos6mini 3.19]# ./linshi 1) huangmenji 2) huimian 3) hulatang 4) roujiamo Please choose your menu: 1 The price is $15 Please choose your menu: 2 The price is $10 Please choose your menu: 3 The price is $8 Please choose your menu: 4 The price is $6 Please choose your menu: 5 get out [root@centos6mini 3.19]# cat ./linshi #!/bin/bash select menu in huangmenji huimian hulatang roujiamo;do case $REPLY in 1) echo "The price is \$15";; 2) echo "The price is \$10";; 3) echo "The price is \$8";; 4) echo "The price is \$6";; *) echo "get out";break;; esac done
信號捕捉trap
trap '觸發(fā)指令' 信號
自定義進程收到系統(tǒng)發(fā)出的指定信號后,將執(zhí)行觸發(fā)指令 ,而不會執(zhí)行原操作
trap '' 信號 忽略信號的操作
rap '-' 信號 恢復(fù)原信號的操作
trap -p 列出自定義信號操作
trap 所有可選項
[root@centos6mini 3.19]# trap -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX #!/bin/bash trap 'echo “signal:SIGINT"' int # int 相當(dāng)與Ctrl+c trap -p for((i=0;i<=10;i++)) do sleep 1 echo $i done trap '' int #trap '' 信號 忽略信號的操作 trap -p for((i=11;i<=20;i++) do sleep 1 echo $i done trap '-' int #rap '-' 信號 恢復(fù)原信號的操作 trap -p for((i=21;i<=30;i++) do sleep 1 echo $i done
忽略kill -15 ,操作可以成功
忽略kill -9操作 ,不成功,無法忽略kill -9
trap -l,把所有信號打印出來
查看kill -9 和kill -15 對應(yīng)的信號選項
select與case
select 是個無限循環(huán),因此要記住用 break 命令退 出循環(huán),或用 exit 命令終止腳本。也可以按 ctrl+c 退出循環(huán)
select 經(jīng)常和 case 聯(lián)合使用
與 for 循環(huán)類似,可以省略 in list,此時使用位置
- Shell中的循環(huán)語句for、while、until實例講解
- Shell中的for和while循環(huán)詳細總結(jié)
- Shell中的while循環(huán)幾種使用實例詳解
- shell命令while循環(huán)中使用sleep命令代碼示例
- Shell腳本while、until循環(huán)語句簡明教程
- shell腳本實戰(zhàn)-while循環(huán)語句
- linux shell常用循環(huán)與判斷語句(for,while,until,if)使用方法
- Windows Powershell Do While 循環(huán)
- Shell循環(huán)語句的使用(for循環(huán)、while循環(huán)、until循環(huán))
- Shell腳本之while循環(huán)應(yīng)用具體案例
相關(guān)文章
淺談linux中shell變量$#,$@,$0,$1,$2的含義解釋
下面小編就為大家?guī)硪黄獪\談linux中shell變量$#,$@,$0,$1,$2的含義解釋。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03shell腳本正則匹配文件中的Email并寫入到文件中代碼分享
有時我們會處理日志文件,或其他文本文件,并將里面含有的Email讀取出來,可以利用shell處理文件的方法來讀取2014-04-04linux 定時執(zhí)行shell、python腳本的方法
這篇文章主要介紹了linux 定時執(zhí)行shell、python腳本的方法,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-05-05shell子進程多任務(wù)實現(xiàn)進程高并發(fā)
本文主要介紹了shell子進程多任務(wù)實現(xiàn)進程高并發(fā),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07開發(fā)者常用及實用Linux Shell命令備忘錄(小結(jié))
這篇文章主要介紹了開發(fā)者常用及實用Linux Shell命令備忘錄(小結(jié)),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11