2.1 shell語句
選擇執行:
註意:if語句可嵌套
單分支
if 判斷條件;then
條件為真的分支代碼
fi
雙分支
if 判斷條件; then
條件為真的分支代碼
else
條件為假的分支代碼
fi
多分支
if 判斷條件1; then
條件為真的分支代碼
elif 判斷條件2; then
條件為真的分支代碼
elif 判斷條件3; then
條件為真的分支代碼
else
以上條件都為假的分支代碼
fi
例子:
1、編寫腳本/root/bin/createuser.sh,實現如下功能:使用一個用戶名做為參數,如果指定參數的用戶存在,就顯示 其存在,否則添加之;顯示添加的用戶的id號等信息
vim createuser.sh #!/bin/bash read -p "please input username:" username useradd $username &> /dev/null if [ $? -eq 0 ];then echo "add $username user" && id $username else echo "the user already exits" fi
2、編寫腳本/root/bin/checkint.sh,判斷用戶輸入的參數是 否為正整數
vim checkint.sh
#!/bin/bash
read -p "please input a digit:" int
if [[ $int =~ (^[0-9]*[1-9][0-9]*$) ]];then
echo "this digit is positive integer"
else
echo "this digit is not positive integer"
fi
二、條件判斷case語句
語法格式:
case 變量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默認分支
;;
esac
3、編寫腳本/root/bin/yesorno.sh,提示用戶輸入yes或no, 並判斷用戶輸入的是yes還是no,或是其它信息
vim yesorno.sh
#!/bin/bash
read -p "can i help you? yes or no " ans
case $ans in
[yY][eE][sS]|[yY])
echo "ok,come on"
;;
[nN][oO]|[nN])
echo "no,thanks"
;;
*)
echo "byebye"
;;
esac
4、編寫腳本/root/bin/filetype.sh,判斷用戶輸入文件路徑 ,顯示其文件類型(普通,目錄,鏈接,其它文件類型)
vim filetype.sh
#!/bin/bash
read -p "please input file path:" path
a=`ls -l $path|grep -o "^."` #腳本裏面不能使用別名,所以用ls -l
case $a in
-)
echo "common file"
;;
d)
echo "directory file"
;;
l)
echo "linked file"
;;
*)
echo "other file"
;;
esac
三、for循環
語法格式:
for 變量名 in 列表;do
循環體
done
執行機制:
依次將列表中的元素賦值給“變量名”; 每次賦值後即執行一次循環體; 直到列表中的元素耗盡,循環結束
for循環列表生成方式:
(1)直接給出列表
(2)整數列表:
(a){start..end}
(b)$(seq [start [step]] end)
(3)返回列表的命令
$(COMMAND)
(4)使用glob,如:*.sh
(5)變量引用;
$@, $*
5、編寫腳本,提示輸入正整數n的值,計算1+2+…+n的總和
#!/bin/bash
read -p "please input a positive integer:" n
i=1
sum=0
for i in `seq 1 $n`;do
if [[ $n =~ (^[0-9]*[1-9][0-9]*$) ]];then #判斷n是否為正整數
let sum+=i
else
echo "a wrong int" && exit
fi
let i++
done
echo "sum is $sum"
6、計算100以內所有能被3整除的整數之和
#!/bin/bash
sum=0
i=1
for i in {1..100};do
if [ $[$i%3] -eq 0 ];then
let sum+=i
fi
let i++
done
echo $sum
7、打印九九乘法表
#!/bin/bash
for i in {1..9};do
for j in `seq 1 $i`;do
echo -n "$i*$j=$[i*j] "
done
echo
done
8、打印等腰三角形
#!/bin/bash
. functions
read -p "please input line:" line
is_digit $line
#i=*的個數 s=空格個數 l=當前行數
[ $? -ne 0 ] && exit
#循環打印
for l in `seq 1 $line`;do
for s in `seq 1 $[$line-$l]`;do
echo -en " "
done
for i in `seq 1 $[2*$l-1]`;do
if [ $i -eq 1 ];then
color=$[RANDOM%7+31] #定義一個31到37的隨機顏色
echo -en "\e[1;${color};5m*\e[0m" #1代表高亮顯示,5m代表閃爍
elif [ $i -eq $[$l*2-1] ];then
echo -en "\e[1;${color};5m*\e[0m"
else
echo -en "*"
fi
done
echo
done
四、while循環
語法格式:
while CONDITION; do
循環體
done
CONDITION:循環控制條件;進入循環之前,先做一次判斷;每一次循環之後會再次做判斷;條件為“true”,則執行一次循環;直到條件測試狀態為“false”終止循環
因此:CONDTION一般應該有循環控制變量;而此變量的值會在循環體不斷地被修正
進入條件:CONDITION為true
退出條件:CONDITION為false
9、編寫腳本,求100以內所有正奇數之和
#!/bin/bash
i=1
sum=0
while [ $i -le 100 ];do
if [ $[$i%2] -ne 0 ];then
let sum+=i
fi
let i++
done
echo "sum is $sum"
10、編寫腳本,利用變量RANDOM生成10個隨機數字,輸出 這個10數字,並顯示其中的最大值和最小值
#!/bin/bash
i=1
a=$RANDOM
max=$a
min=$a
while [ $i -le 10 ];do
[ $max -lt $a ] && max=$a
[ $min -gt $a ] && min=$a
a=$RANDOM
echo "$a"
let i++
done
echo "max is $max"
echo "min is $min"
11、編寫腳本,實現打印國際象棋棋盤
#!/bin/bash
red="\e[41m \e[0m"
white="\e[47m \e[0m"
for i in `seq 1 8`;do #這裏定義了一個8行的棋盤
if [ $[i%2] -eq 0 ];then #判斷是否為偶行
for j in {1..4};do #四個偶數行就循環四遍紅白色
echo -en "$red$white"
done
else
for j in {1..4};do #四個奇數行循環白紅行
echo -en "$white$red"
done
fi
echo
done
12、後續六個字符串:efbaf275cd、4be9c40b8b、 44b2395c46、f8c8873ce0、b902c16c8b、ad865d2f63 是通過對隨機數變量RANDOM隨機執行命令: echo $RANDOM|md5sum|cut –c1-10 後的結果,請破解這些字符串對應的RANDOM值
#!/bin/bash
key_num_array=(efbaf275cd 4be9c40b8b 44b2395c46 f8c8873ce0 b902c16c8b ad865d2f63) #將這些字符串賦值到數組裏,方便調用
for true_num in `seq 0 65535`;do #RANDOM值為0~65535
key_num=`echo $true_num | md5sum | cut -c 1-10`
for num in ${key_num_array[*]}; do
if [ "$key_num" == "$num" ];then
echo "$num --> $true_num"
fi
done
done
五、Until循環(與while條件相反,比較少用)
語法格式:
until CONDITION; do
循環體
done
進入條件: CONDITION 為false
退出條件: CONDITION 為true
13、每隔3秒鐘到系統上獲取已經登錄的用戶的信息;如果發 現用戶hacker登錄,則將登錄時間和主機記錄於日誌 /var/log/login.log中,並退出腳本
#!/bin/bash
until who |grep "^hacker\>";do
sleep 3
done
who|egrep -o "^hacker.*"|sed -r ‘s/^hacker[[:space:]]+‘// >> /app/hacker.log #小編這裏記錄於這個路徑
echo "you should logout"| mail hacker
14、隨機生成10以內的數字,實現猜字遊戲,提示比較大或小 ,相等則退出
#!/bin/bash
num=$[$RANDOM%10+1]
read -p "please guess:" i
until [ $num -eq $i ]; do
if [ $i -lt $num ]; then
echo "less,guess again"
else
echo "bigger,guess again"
fi
read -p "please guess:" i
done
echo "guess succeed!";exit
六、循環控制語句continue
用於循環體中
continue [N]:提前結束第N層的本輪循環,而直接進入下一 輪判斷;最內層為第1層
語法格式:
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
continue
fi
CMDn
...
Done
舉例奇數相加並跳過51
#!/bin/bash
for((i=1,sum=0;i<=100;i++));do #奇數相加
[ $i -eq 51 ] && continue #結束本輪循環,就是跳過51執行下面的奇數53
[ $[i%2] -eq 1 ] && let sum+=i
done
echo "sum is $sum"
unset i sum
七、循環控制語句break
用於循環體中
break [N]:提前結束第N層循環,最內層為第1層
語法格式:
while CONDTIITON1; do
CMD1
...
if CONDITION2; then break
fi
CMDn
...
Done
舉例結束點餐
#!/bin/bash
cat << EOF
1 yangroufan
2 mifan
3 hulatang
4 jiaozi
5 lamian
6 huimian
7 exit
EOF
while true;do
read -p "please choose: " wufan
case $wufan in
1|4)
echo "price 20"
;;
2|5)
echo "price 15"
;;
3|6)
echo "price 10"
;;
7)
break #輸入7就直接退出這個循環
;;
*)
echo "no this option"
;;
esac
done
八、循環控制shift命令
shift [n]
用於將參量列表 list 左移指定次數
參量列表 list 一旦被移動,最左端的那個參數就從列表中刪 除。while 循環遍歷位置參量列表時,常用到 shift
#!/bin/bash
while (( $# > 0 ));do
echo $*
shift
done
九、select與case
select 循環主要用於創建菜單,按數字順序排列的,它是個無限循環,因此要記住用 break 命令退 出循環,或用 exit 命令終止腳本。也可以按 ctrl+c 退出循環
舉例創建菜單並退出菜單:
#!/bin/bash
select menu in yangroufan gaojiaofan huimian hulatang quit;do
case $REPLY in
1|3)
echo "price is 20"
;;
2|4)
echo "price is 15"
;;
5)
break
;;
*)
echo "no this option"
;;
esac
done
select 經常和 case 聯合使用
十、信號捕捉trap :捕捉到信號後自定義處理
trap ‘觸發指令‘ 信號
自定義進程收到系統發出的指定信號後,將執行觸發指令 ,而不會執行原操作 trap ‘‘ 信號 忽略信號的操作
trap ‘-‘ 信號 恢復原信號的操作
trap -p 列出自定義信號操作
舉例打印數字捕捉信號
#!/bin/bash
trap ‘echo press ctrl+c‘ 2 #提示按了ctrl+c
for((i=0;i<10;i++));do
sleep 1
echo $i
done
trap ‘‘ INT #不提示
for((i=10;i<15;i++));do
sleep 1
echo $i
done
trap ‘-‘ 2 #恢復ctrl+c的停止作用
for((i=15;i<20;i++));do
sleep 1
echo $i
done
2.1 shell語句