組合測試條件
第一種方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[ -e FILE ] && [ -r FILE ]
第二種方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必須使用測試命令進行;
# [ -z “$HOSTNAME” -o $HOSTNAME "= =\"localhost.localdomain" ] && hostname www.QUAN.com 判斷hostname是否為空或者是否為localhost.localdomain,如果有一個條件成立,執行hostname命令 # [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab判斷文件是否存在并且可執行
課堂練習:
1 、chmod -rw /tmp/file1 ,編寫腳本/root/bin/per.sh,判斷當前用戶對/tmp/fiile1件 文件 是否不可讀且不可寫
首先vi /root/bin/per.sh編輯腳本
#!/bin/bash [ -r /tmp/file1 -a -w /tmp/file1 ] && echo "`whoami` can read and write " || echo "`whoami` can not read and write "
然后:wq存盤退出
2 、編寫腳本/root/bin/nologin.sh 和login.sh, 實現禁止和充許普通用戶登錄系統。
vi /root/bin/nologin.sh
#!/bin/bash [ -e /etc/nologin ] && exit || touch /etc/nologin echo "disable user login "
vi /root/bin/login.sh
#!/bin/bash [ -e /etc/nologin ] && rm -f /etc/nologin echo "enable user login "
執行nologin腳本后,普通用戶登錄會出現:
然后在執行login腳本,會恢復正常:
使用read命令接受輸入:
使用read 來把輸入值分配給一個或多個shell 變量:
-p 指定要顯示的提示
-t TIMEOUT
read 從標準輸入中讀取值,給每個單詞分配一個變量,所有剩余單詞都被分配給最后一個變量
read -p “Enter a filename: “ FILE
條件選擇if語句:
選擇執行: 注意:if 語句可嵌套執行
單分支
if 判斷條件:then 條件為真的分支代碼
fi
雙分支
if 判斷條件; then 條件為真的分支代碼
else 條件為假的分支代碼
fi
多分支
if CONDITION1 ; then if-true elif CONDITION2 ; then if-ture elif CONDITION3 ; then if-ture else all-false fi
*逐條件進行判斷,第一次遇為“真”條件時,執行其分支,而后結束整個if 語句
if實例:
根據命令的退出狀態來執行命令
if ping -c1 -W2 station1 &> /dev/null; then echo 'Station1 is UP' elif grep "station1" ~/maintenance.txt &> /dev/null then echo 'Station1 is undergoing maintenance‘ else echo 'Station1 is unexpectedly DOWN!' exit 1 fi
條件判斷case語句:
case 用變量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
…
*)
默認分支
;;
esac
case支持glob風格的通配符:
*: 任意長度任意字符
?: 任意單個字符
[]:指定范圍內的任意單個字符
a|b: a或b
練習:
1 、寫一個腳本/root/bin/createuser.sh ,實現如下功能:使用一個用戶名做為參數,如果指定參數的用戶存在,就顯示其存在,否則添加之;顯示添加的用戶的id 號等信息
vi /root/bin/createuser.sh
#!/bin/bash if id $1 &> /dev/null ; then echo "$1 is exsit,the info is `id $1`" else useradd $1 && echo "useradd is successful ,the info is `id $1`" fi
2 、寫一個腳本/root/bin/yesorno.sh ,提示用戶輸入yes或 或no, 并判斷用戶輸入的是yes 還是no, 或是其它信息
vi /root/bin/yesorno.sh
#!/bin/bash echo -e "Do you agree marry me?yes or no:\c" read answer echo "your answer is $answer"
:wq存盤退出 執行yesorno腳本
3 、寫一個腳本/root/bin/filetype.sh, 判斷用戶輸入文件路徑,顯示其文件類型(普通,目錄,鏈接,其它文件類型)
#!/bin/bash read -p "please input a path of the file :" files if [ -b $files ];then echo "該文件是塊設備" elif [ -c $files ] ;then echo "該文件是字符設備" elif [ -f $files ];then echo "該文件是普通文件" elif [ -h $files ];then echo "該文件是符號鏈接文件" elif [ -p $files ];then echo "該文件是管道文件" elif [ -S $files ];then echo "該文件是套接字文件" elif [ -d $files ];then echo "該文件是目錄文件" else echo "文件或目錄不存在" fi
:wq存盤退出,執行腳本
4 、寫一個腳本/root/bin/checkint.sh, 判斷用戶輸入的參數是否為正整數
vi /root/bin/checkint.sh
!/bin/bash read -p "please input :" arg if [[ $arg =~ ^[[:digit:]]+$ ]] && [ $(expr $arg + 0) != 0 ] ;then echo "The number is positive integer" else echo "The number is not positive integer" fi
:wq 存盤退出,執行腳本
循環
循環執行:
將某代碼段重復運行多次
重復運行多少次:
循環次數事先已知
循環次數事先未知
有進入條件和退出條件
for, while, until
for循環
for 變量名 in 列表;do
循環體
done
執行機制 :
依次將列表中的元素賦值給“變量名”; 每次賦值后即執行一次循環體; 直到列表中的元素耗盡,循環 結束
列表生成方式:
(1) 直接給出 列表
(2) 整數列表:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 返回列表的命令
$(COMMAND)
(4) 使用glob,如:*.sh
(5) 變量引用;
$@, $*
添加10個用戶user1-user10 ,密碼同用戶名
#!/bin/bash # Version: 0.1 # Description: Batch to create user # 1.File to import # 2.user1-user10 if [ -s userfile.t ]; then for i in $(cat userfile.t) do useradd $i echo $i | passwd --stdin $i > /dev/null done echo "The user has been created" else for i in $(seq 1 10) do useradd user$i echo user$i | passwd --stdin user$i > /dev/null done echo "The user has been created" fi
然后執行下腳本
如果重復執行腳本,會出現下面的提示:
創建一個刪除腳本:
#!/bin/bash # Version: 0.1 # Description: Batch delete user # 1.File to import # 2.user1-user10 if [ -s userfile.t ]; then for i in $(cat userfile.t) do userdel -r $i > /dev/null done echo "The user has been deleted" else for i in $(seq 1 10) do userdel -r user$i > /dev/null done echo "The user has been deleted" fi
執行腳本看一下:
/etc/rc.d/rc3.d 目錄下分別有多個以K開頭和以S開頭的文件 ;分別讀取每個文件,以K開頭的文件輸出為文件加stop,以S開頭的文件輸出為文件名加start;“K34filename stop” “S66filename start”
編輯腳本,vi file-rc3.d
#!/bin/bash for file in `ls /etc/rc.d/rc3.d`;do if echo $file | grep -q "^S" ;then echo "$file start" elif echo $file | grep -q "^K" ;then echo "$file stop" fi done
寫一個腳本,提示輸入正整數n 的值,計算1+2+3+…n的總和
#!/bin/bash read -p "please input a number:" n sum=0 for i in $(seq 1 $n);do let sum+=$i done echo "the sum is $sum"
執行腳本 輸入的數字表示的是 從1開始的n個數字 執行腳本相加求和
寫一個腳本 ,提示請輸入網絡地址,如192.168.0.0 ,判斷輸入的網段中主機在線狀態
#!/bin/bash file=`mktemp /tmp/pingip.XXXXXX` read -p "please input the ip adress :" ip i=`echo $ip | cut -d'.' -f1-3` for z in {1..255};do { ip=$i.$z ping -c1 -W1 $ip &> /del/null && (echo "$ip is up" ) && echo ip> > $file }& done sleep 1 echo "`cat $file | wc -l`online" rm -f $file &> /dev/null
打印九九乘法表
#!/bin/bash for i in {1..9};do for j in $(seq 1 $i) ;do echo -ne "${j}x${i}=$[i*j]\t" done echo done
while循環
while CONDITION; do
循環體
done
CONDITION :循環控制條件;進入循環之前,先做一次判斷;每一次循環之后會再次做判斷;條件為“true” ,則執行
一次循環;直到條件測試狀態為“false” 終止循環
因此:CONDTION 一般應該有循環控制變量;而此變量的值會在循環體不斷地被修正
進入條件:CONDITION 為true; ;
退出條件:CONDITION 為false
練習
1 、求100 以內所有正整數之和
sum=0 i=0 while [ $i -le 100 ] ;do let sum+=$i let i++ done echo $sum
2、打印九九乘法表
#!/bin/bash i=1 j=1 while [ $i -le 9 ] ;do while [ $j -le $i ] ;do echo -ne "${j}x${i}=$[i*j]\t" let j+=1 done let i+=1 j=1 echo done
3、打印國際象棋棋盤
#!/bin/bash for i in $(seq 1 8);do for j in $(seq 1 8);do [ $[i%2-$j%2] -eq 0 ] && echo -ne "\033[44m \033[0m" || echo -ne "\033[47m \033[0m" let j++ done echo "" let i++ done
#!/bin/bash let x=y=1 h=8 while [ $x -le $h ];do while [ $y -le $h ];do if [ $[(x+y)%2] -eq 0 ] ;then echo -en "\033[41m \033[0m" else echo -en "\033[47m \033[0m" fi let y+=1 done echo let x+=1,y=1 done
4、利用變量RANDOM 生成10 個隨機數字,輸出這個10 數字,并顯示其中的最大者和最小者
#!/bin/bash let i=0,min=max=$RANDOM echo "$min " while [ $i -lt 9 ];do ran=$RANDOM echo "$ran " if [ $ran -ge $max ];then let max=ran fi if [ $ran -le $min ];then let min=ran fi let i+=1 done echo "the max is $max ,the min is $min"
until循環
until CONDITION; do
循環體
done
:進入條件:CONDITION 為false
:退出條件:CONDITION 為true
循環控制語句continue
用于循環體中
continue [N] :提前結束第N 層的本輪循環,而直接進入下一輪判斷;最內層為第1層
while CONDTIITON1; do CMD1 ... if CONDITION2; then continue fi CMDn ... done
控制循環語句break
用于循環體中
break [N] :提前結束第N 層循環,最內層為第1層
while CONDTIITON1; do CMD1 ... if CONDITION2; then break fi CMDn ... done
創建無限循環:
while true; do
循環體
done
until false; do
循環體
Done
練習
隨機生成10 以內的數字,實現猜字游戲,提示比較大或小,相等則退出。
#!/bin/bash lim=10 let key=$RANDOM%lim read -p "please input a number less than $lim: " num until false;do if [ $num -le $lim &> /dev/null ] && [ $num -ge 0 &> /dev/null] ;then if [ $num -lt $key ];then read -p "is small,please input again: " num elif [ $num -gt $key ];then read -p "is big,please input again: " num else echo "you are right,man gave me five" break fi else read -p "error,please input a number less than ten: " num fi done
特殊用法
while 循環的特殊用法(遍歷文件的每一行):
while read line; do
循環體
done < /PATH/FROM/SOMEFILE
依次讀取/PATH/FROM/SOMEFILE 文件中的每一行,且將行賦值給變量line
雙小括號方法,即((…)) 格式,也可以用于算術運算
雙小括號方法也可以使bash Shell 實現C 語言風格的變量操作
#I=10
#((I++))
for循環的特殊格式:
for(( 控制變量初始化; 條件判斷表達式; 控制變量的修正表達式))
do
循環體
done
控制變量初始化:僅在運行到循環代碼段時執行一次
控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算,而后再做條件判斷
原創文章,作者:舊城以西,如若轉載,請注明出處:http://www.www58058.com/35755
shell腳本作為一個基本能力,需要我們多加練習,才能熟練掌握,我們可以通過寫的練習總結出各個循環語句的區別,來實現對循壞語句的快速選擇和應用。