IC數字前端設計開發22 (shell迴圈:for、while、until——詳解)
來自:http://blog.51cto.com/12105235/2090749
迴圈執行 :將某程式碼段重複執行多次; 重複執行多少次: 迴圈次數事先已知 ;迴圈次數事先未知 ;有進入條件和退出條件。
三種迴圈體:for、while、until。
再迴圈前前介紹步進,在迴圈中經常用到步進。
步進
顯示1-10
[[email protected] app]# echo {1..10} 1 2 3 4 5 6 7 8 9 10 [[email protected] app]# echo $(seq 1 10) 1 2 3 4 5 6 7 8 9 10
1-10 遞加
[[email protected] app]# echo {1..10..2}
1 3 5 7 9
[[email protected] app]# echo $(seq 1 2 10)
1 3 5 7 9
1-10 遞減
[[email protected] app]# echo {10..1..2}
10 8 6 4 2
[[email protected] app]# echo $(seq 10 -2 1)
10 8 6 4 2
1-100間的奇數和偶數
[[email protected] 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
[ [email protected] 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
[[email protected] 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
[ [email protected] 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位包含數字、大小寫字母、符號的密碼
cat /dev/urandom |tr -dc '[email protected]_#?.,' |head -c 16
tr -d 和 tr -dc 的用法
[[email protected] app]# echo 12324345 |tr -d 2 #不要數字2
134345
[[email protected] app]# echo 12324345 |tr -dc 2 #支取數字2
22
for迴圈
for 變數名 in 列表;do
迴圈體
done
執行機制:
依次將列表中的元素賦值給“變數名”; 每次賦值後即執 行一次迴圈體; 直到列表中的元素耗盡,迴圈結束
for迴圈的列表生成方式:
(1) 直接給出列表
(2) 整數列表:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 返回列表的命令 $(COMMAND)
(4) 使用glob,如:*.sh
(5) 變數引用; [email protected], $*
批量建立user1至user10,要求設定隨機16位密碼,包含數字、大小寫字母、符號。並要求使用者使用密碼首次登入後,強制設定新密碼。
#!/bin/bash
> /root/user.log
for i in {1..10};do
#建立十個使用者
useradd user$i && echo user$i is created
#隨機生成密碼
password=$(cat /dev/urandom |tr -dc '[email protected]_#?.,' |head -c 16)
#將使用者和密碼匯出
echo user$i:$password >> /root/user.log
#設定密碼
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
[[email protected] ~]# ./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 '[email protected]_#?.,' |head -c 16) #生成隨機數
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 #檢視檔案內容確定迴圈次數
if [[ $i =~ ^K.* ]];then
echo "$i stop"
elif [[ $i =~ ^S.* ]];then
echo "$i start"
fi
done
[[email protected] app]# ./linshi
K05wdaemon stop
K10saslauthd stop
K15htcacheclean stop
K15httpd stop
K30spice-vdagentd stop
K50dnsmasq stop
K50kdump stop
K73winbind stop
K74ntpd stop
...省略...
編寫指令碼,提示輸入正整數n的值,計算1+2+…+n的總和
#!/bin/bash
read -p "請輸入一個正整數" s
w=0
if [[ "$s" =~ ^[0-9]+$ ]] ;then
for i in $(seq 1 $s) ;do
w=$[$w+$i]
done
echo "整數1到$s的和為$w"
else echo "請輸入正整數"
fi
計算100以內所有能被3整除的整數之和
方法一:
[[email protected] 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目錄下建立10個html檔案,檔名格式為數字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 '[email protected]_#?.,' |head -c 8)
touch $i$w.html
done
方法二:
if ! [ -d /testdir ];then #判斷檔案是否存在
mkdir /testdir &> /dev/null #如果沒有建立檔案
fi
for i in {1..10};do
touch /testdir/$i`cat /dev/urandom |tr -dc [:alpha:] |head -c 8`.html #建立檔案
done
探測區域網內的主機
172.18.250-254.X
能ping通顯示並儲存至/root/ip.log
要求並行探測提高效率。
[[email protected] 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
[[email protected] 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
列印國際象棋棋盤
方法一:
[[email protected] 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迴圈
while CONDITION; do
迴圈體
done
CONDITION:迴圈控制條件;進入迴圈之前,先做一次判 斷;每一次迴圈之後會再次做判斷;條件為“true”,則執行 一次迴圈;直到條件測試狀態為“false”終止迴圈
因此:CONDTION一般應該有迴圈控制變數;而此變數的值 會在迴圈體不斷地被修正
進入條件:CONDITION為true
退出條件:CONDITION為false
“:” 和true的返回值都為真
[[email protected] zuoye]# true
[[email protected] zuoye]# echo $?
0
[[email protected] zuoye]# :
[[email protected] zuoye]# echo $?
0
判斷/var/目錄下所有檔案的型別
[[email protected] 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目錄下普通檔案數量: $zc\nvar目錄下子目錄數量:$dc\nvar目錄下連結檔案數量:$lc\nvar目錄下字元型別檔案數量: $cc\nvar
目錄下塊裝置檔案數量:$bc\n其他型別檔案數量:$oc"
rm -f /tmp/var_ftype.txt
[[email protected] 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目錄下普通檔案數量: 0
var目錄下子目錄數量:19
var目錄下連結檔案數量:1
var目錄下字元型別檔案數量: 0
var
目錄下塊裝置檔案數量:0
其他型別檔案數量:0
編寫指令碼,求100以內所有正奇數之和
方法一:
[[email protected] 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
[[email protected] zuoye]# echo {1..100..2}|tr " " + |bc
2500
方法二:
[[email protected] 3.19]# ./1
2500
[[email protected] 3.19]# cat 1
#!/bin/bash
u=0
for i in {1..100..2}; do
let u+=i
done
echo $u
方法三:
[[email protected] 3.19]# ./1
2500
[[email protected] 3.19]# cat 1
#!/bin/bash
u=0
i=1
while [ $i -le 100 ] ;do
let u+=i
let i+=2
done
echo $u
編寫指令碼,提示請輸入網路地址,如192.168.0.0,判斷輸入的網段中主機線上狀態,並統計線上和離線主機各多少
方式一:
#!/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 "通的主機數為 : $w"
y=`cat /app/w.txt |wc -l`
echo "不通的主機數為 : $y"
rm -rf /app/w.txt /app/e.txt
編寫指令碼,列印九九乘法表
[[email protected] 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
[[email protected] 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個隨機數字,輸出這個10數字,並顯示其中的最大值和最小值
[[email protected] 3.19]# ./4
25955
25748
16113
19729
8944
19049
16202
20067
30609
4309
最大值: 30609
最小值: 4309
[[email protected] 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、編寫指令碼,實現列印國際象棋棋盤[
[[email protected] 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
後續六個字串:efbaf275cd、4be9c40b8b、44b2395c46、f8c8873ce0、b902c16c8b、ad865d2f63是通過對隨機數變數RANDOM隨機執行命令:
echo $RANDOM|md5sum|cut –c1-10
後的結果,請破解這些字串對應的RANDOM值
方法一:
#!/bin/bash
>6
while true ;do
while true ;do
w=`echo $RANDOM ` #定義變數--隨機數隨時在變化,給他賦值一個變數,後邊取值就不在變化了
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
[[email protected] ~]# 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
$#和$*差別
[[email protected] 3.19]# ./linshi 1 2 2 3 4
1 2 2 3 4
2 2 3 4
2 3 4
3 4
4
[[email protected] 3.19]# cat linshi
#!/bin/bash
while [ $# -gt 0 ];do
echo $*
shift
done
[[email protected] 3.19]# ./linshi 1 2 2 3 4
5
4
3
2
1
[[email protected] 3.19]# cat linshi
#!/bin/bash
while [ $# -gt 0 ];do
echo $#
shift
done
使用一條命令,依次建立指定的使用者。如執行createuser.sh tom bob alice harry
方法1:
[[email protected] 3.19]# ./linshi createuser.sh tom bob alice harry
createuser.sh 使用者建立成功
tom 使用者建立成功
bob 使用者建立成功
alice 使用者建立成功
harry 使用者建立成功
[[email protected] 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 使用者建立成功"
shift
done
刪除使用者
[[email protected] 3.19]# ./linshi createuser.sh tom bob alice harry
createuser.sh 使用者刪除成功
tom 使用者刪除成功
bob 使用者刪除成功
alice 使用者刪除成功
harry 使用者刪除成功
[[email protected] 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秒鐘到系統上獲取已經登入的使用者的資訊;如果發現使用者hacker登入,則將登入時間和主機記錄於日誌/var/log/login.log中,並退出指令碼
#!/bin/bash
while true;do
if $(ps -au |grep "^hacker.*" &> /dev/null);then #監測前臺終端上有沒有使用者登陸資訊
echo $(ps -au |grep "^hacker.*" |tr -s " " |cut -d" " -f1,7,9) >> /var/log/login.log
#將使用者登陸資訊儲存到日誌檔案中/var/log/login.log
break #推出監測
else
sleep 3s #三秒已監測,防止程式太多佔用cpu
fi
done
隨機生成10以內的數字,實現猜字遊戲,提示比較大或小,相等則退出
[[email protected] 3.19]# ./linshi
請輸入數值 : 1
錯了 ,小了
請輸入數值 : 9
錯誤,大了
請輸入數值 : 5
猜對了
[[email protected] 3.19]# cat linshi
#!/bin/bash
qe=$( echo $[$RANDOM%10] )
while true ;do
read -p "請輸入數值 : " qw
if [ $qw -gt $qe ] ;then
echo "錯誤,大了"
elif [ $qw -lt $qe ] ;then
echo "錯了 ,小了"
elif [ $qe -eq $qw ];then
echo "猜對了"
break
fi
done
用檔名做為引數,統計所有引數檔案的總行數
[[email protected] 3.19]# ./linshi /etc/passwd /etc/sysconfig/network-scripts/ifcfg-eth1 /etc/passwd
89
[[email protected] 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、用二個以上的數字為引數,顯示其中的最大值和最小值
方法一:
#!/bin/bash
min=$1 #最小值等於第一個數值
max=$1 #最大數等於第一個數值
while [ $# -gt 0 ];do #進行數值數量進行判斷,做迴圈
value=$1 #定義變數
if [ $value -gt $max ];then #當第二個數大於第一個數時
max=$value #最大值等於後一個數值,對max從新賦與新的值
elif [ $value -lt $min ];then #當第二個數大於第一個數時
min=$value #最小值等於後一個數值 對min從新賦與新的值
fi
shift #不管前面判斷是否成立,都進行數列左移,
done
echo "min $min"
echo "max $max"
方法二:
#!/bin/bash
if [ $# -lt 2 ];then #對輸入數字數量進行檢測
echo "type more than two numbers"
exit 1
fi
small=$(echo $* |xargs -n1 |sort -n |head -n 1) #進行數值排序
big=$(echo $* |xargs -n1 |sort -n |tail -n 1)
echo "Maximum number is $big"
echo "Minimum number is $small"
[[email protected] ~]# echo 1 -3 -99 46 7 32 43 2133 312 |xargs -n1 #以一數列進行顯示
1
-3
-99
46
7
32
43
2133
312
read 示例:
[[email protected] 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
[[email protected] 3.19]# read bing < test。txt
[[email protected] 3.19]# echo $bing
hello
^C
[[email protected] 3.19]# while read name ; do echo $name ;done # 沒有指定輸入
123 #輸入
123 #輸出
qwe #輸入
qwe #輸出
asd #輸入
asd #輸出
zxc #輸入
zxc #輸出
^C^[[A^C
[[email protected] 3.19]# while read name ; do echo $name ;done <6 #name為變數,輸入來自檔案檔案內容讀取完了,迴圈停止
hello
qweqew
12341234
asdas
ads
sda
sad
asd
as
asd
as
read 示例:
顯示UID小於1000的為sys user,大於等於1000的為comm user。
[[email protected] 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 #每次迴圈引用檔案內容一行,進行操作,引用完了,迴圈停止。
[[email protected] 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
找出分割槽利用率大於10%的分割槽,併發出警告/dev/sdaX will be full: 15%要求使用while read來實現
答案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
[[email protected] 3.19]# df |grep /dev/sd >/app/zuoye/3.19/6
[[email protected] 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
[[email protected] 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實現
#!/bin/bash
df |grep /dev/sd |while read disk;do
diskused=$(echo $disk |sed -r 's/.* ([0-9]+)%.*/\1/')
diskname=$(echo $disk |sed -r '[email protected](/dev/sd[[:lower:]][[:digit:]]).*@\[email protected]')
if (( $diskused > 10 ));then
echo "$diskname will be full:$diskused%"
fi
done
until迴圈
until CONDITION; do
迴圈體
done
進入條件: CONDITION 為false
退出條件: CONDITION 為true
迴圈控制語句continue
用於迴圈體中
continue [N]:提前結束第N層的本輪迴圈,而直接進入下一 輪判斷;最內層為第1層
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
continue
fi
CMDn
迴圈控制語句break
用於迴圈體中
break [N]:提前結束第N層迴圈,最內層為第1層
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
break
fi
CMDn
...
done
迴圈控制shift命令
shift [n]
用於將參量列表 list 左移指定次數,預設為左移一次。
參量列表 list 一旦被移動,最左端的那個引數就從列表中刪 除。while 迴圈遍歷位置參量列表時,常用到 shift
./doit.sh a b c d e f g h
./shfit.sh a b c d e f g h
特殊用法
1、while迴圈的特殊用法(遍歷檔案的每一行):
while read line; do
迴圈體
done < /PATH/FROM/SOMEFILE
依次讀取/PATH/FROM/SOMEFILE檔案中的每一行,且將 行賦值給變數line
2、雙小括號方法,即((…))格式,也可以用於算術運算
雙小括號方法也可以使bash Shell實現C語言風格的變數操作
I=10
((I++))
for迴圈的特殊格式: for ((控制變數初始化;條件判斷表示式;控制變數的修正表達 式))
do
迴圈體
done
控制變數初始化:僅在執行到迴圈程式碼段時執行一次
控制變數的修正表示式:每輪迴圈結束會先進行控制變數修 正運算,而後再做條件判斷
select迴圈與選單
select variable in list
do
迴圈體命令
done
select 迴圈主要用於建立選單,按數字順序排列的 選單項將顯示在標準錯誤上,並顯示 PS3 提示符, 等待使用者輸入
使用者輸入選單列表中的某個數字,執行相應的命令
使用者輸入被儲存在內建變數 REPLY 中
select與case
select 是個無限迴圈,因此要記住用 break 命令退 出迴圈,或用 exit 命令終止指令碼。也可以按 ctrl+c 退出迴圈
select 經常和 case 聯合使用
與 for 迴圈類似,可以省略 in list,此時使用位置 參量
訊號捕捉trap
trap '觸發指令' 訊號
自定義程序收到系統發出的指定訊號後,將執行觸發指令 ,而不會執行原操作
trap '' 訊號
忽略訊號的操作
trap '-' 訊號
恢復原訊號的操作
trap -p
列出自定義訊號操作
檔案測試
-z string 測試指定字元是否為空,空著真,非空為假 -n string 測試指定字串是否為不空,空為假 非空為真 -e FILE 測試檔案是否存在 -f file 測試檔案是否為普通檔案 -d file 測試指定路徑是否為目錄 -r file 測試檔案對當前使用者是否可讀 -w file 測試檔案對當前使用者是否可寫 -x file 測試檔案對當前使用者是都可執行 -z 是否為空 為空則為真 -a 是否不空 -u file :是否存在且擁有suid許可權 -g file :是否存在且擁有sgid許可權 -k file :是否存在且擁有sticky許可權
[[email protected] 3.19]# [ -n "" ]&& echo true #空為假
[[email protected] 3.19]# [ -n "1" ]&& echo true #非空為真
true
[[email protected] 3.19]# [ -n " " ]&& echo true #非空為真
true
[[email protected] 3.19]# [ -n ]&& echo true #非空為真
true
[[email protected] 3.19]# [ -z ]&& echo true #空為真
true
[[email protected] 3.19]# [ -z "" ]&&echo true #空為真
true
[[email protected] 3.19]# [ -z "1" ] && echo true "#非空為假
[[email protected] 3.19]# [ -z " " ] && echo true #非空為假
掃描/etc/passwd檔案每一行,如發現GECOS欄位為空,則填充使用者名稱和單位電話為62985600,並提示該使用者的GECOS資訊修改成功。
#!/bin/bash
cat /etc/passwd |while read userline;do #用管道實現給迴圈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
特殊用法
雙小括號方法,即((…))格式,也可以用於算術運算
雙小括號方法也可以使bash Shell實現C語言風格的變數操作
I=10
((I++))
for迴圈的特殊格式:
for ((控制變數初始化;條件判斷表示式;控制變數的修正表達 式))
do
迴圈體
done
控制變數初始化:僅在執行到迴圈程式碼段時執行一次
控制變數的修正表示式:每輪迴圈結束會先進行控制變數修 正運算,而後再做條件判斷
練習:計算從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迴圈與選單
select variable in list
do
迴圈體命令
done
select 迴圈主要用於建立選單,按數字順序排列的 選單項將顯示在標準錯誤上,並顯示 PS3 提示符, 等待使用者輸入
PS3="Please choose your menu: "
使用者輸入選單列表中的某個數字,執行相應的命令
使用者輸入被儲存在內建變數 REPLY 中
[[email protected] 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
[[email protected] 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 '觸發指令' 訊號
自定義程序收到系統發出的指定訊號後,將執行觸發指令 ,而不會執行原操作
trap '' 訊號 忽略訊號的操作
rap '-' 訊號 恢復原訊號的操作
trap -p 列出自定義訊號操作
trap 所有可選項
[[email protected] 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 相當與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 '-' 訊號 恢復原訊號的操作
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 對應的訊號選項
select與case
select 是個無限迴圈,因此要記住用 break 命令退 出迴圈,或用 exit 命令終止指令碼。也可以按 ctrl+c 退出迴圈
select 經常和 case 聯合使用
與 for 迴圈類似,可以省略 in list,此時使用位置