linux之基礎shell腳本程式設計1 基礎變量指派
linux之基礎shell腳本程式設計2 if語句循環判斷
linux之基礎shell腳本程式設計3 函數數組
linux之基礎shell腳本程式設計4 字元串操作,變量指派,配置使用者環境
本章所學指令:
if
case
while
for
unit
break
continue
五,流程控制
5.1 使用read指令來接受輸入
使用read來把輸入值配置設定給一個或多個shell變量:
-p :指定要顯示的提示
-t :TIMEOUT
比如:
read -p "print a filename:" file
注意:read 從标準輸入中讀取值,給每一個單詞配置設定一個變量,所有剩餘單詞都被配置設定給最後一個變量
5.2 條件選擇if語句
if語句是選擇執行,并且可以嵌套執行
單分支:
if 判斷條件 ; then
條件為真的分支代碼
fi
if [ $1 -gt 60 ];then
echo "the grade is pass"
fi
雙分支:
if 判斷條件 ; then
條件為真的分支代碼
else
條件為假的分支代碼
fi
if [ $1 -gt 60 ];then
echo "the grade is pass"
else
echo "the grade is not pass"
fi
多分支:
逐條件進行判斷,第一次遇為“真”條件時,執行其分支,而後結束整個if語句
if CONDITION1; then
if-true
elif CONDITION2; then
if-ture
elif CONDITION3; then
if-ture
...
else
all-false
fi
5.3 條件判斷case語句
case 變量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
預設分支
;;
esac
case支援glob風格的通配符:
* : 任意長度任意字元
? : 任意單個字元
[] :指定範圍内的任意單個字元
a|b : a或b
實戰訓練5
1、寫一個腳本/root/bin/createuser.sh,實作如下功能: 使用一個使用者名做為參數,如果指定參數的使用者存在,就顯示其存在,否則添加之;顯示添加的使用者的id号等資訊
##方法一
[[email protected] test]# cat createuser.sh
#!/bin/bash
id $1 &>/dev/null && (echo '該使用者已存在,資訊為:' ; id $1) || ( useradd $1 ; echo '添加成功,資訊為:' ; id $1)
[[email protected] test]# bash createuser.sh user01
添加成功,資訊為:
uid=1005(user01) gid=1005(user01) groups=1005(user01)
[[email protected] test]# bash createuser.sh user01
該使用者已存在,資訊為:
uid=1005(user01) gid=1005(user01) groups=1005(user01)
##方法二
#!/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,或是其它資訊
#!/bin/bash
read -p "please input 'yes' or 'no' : " string
case $string in
[Yy][Ee][sS]|Y|y)
echo "you input is yes"
;;
[Nn][oO]|N|n)
echo "you input is no"
;;
*)
echo "you input is other info"
;;
esac
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
4、寫一個腳本/root/bin/checkint.sh,判斷使用者輸入的參數是否為正整數
#!/bin/bash
read -p "please input :" arg
if [[ $arg =~ ^[[:digit:]]+$ ]] && [ $(expr $arg + 0) != 0 ] ;then
echo "是正整數"
else
echo "不是正整數"
fi
六,循環
循環執行:
- 将某代碼重複運作多次
- 重複運作多次
- 循環次數事先已知
- 循環次數事先未知
- 有進入條件和退出條件
for,while,until
6.1 for循環
for 變量名 in 清單;do
循環體
done
執行機制:依次将清單中的元素指派給"變量名";每次指派後即執行一次循環體,直到類表中的元素耗盡,循環結束
清單生成方式:
(1) 直接給出清單
(2) 整數清單:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 傳回清單的指令 $(COMMAND)
(4) 使用glob,如:*.sh
(5) 變量引用: $@, $*
實戰訓練6
要求:用for實作
1、判斷/var/目錄下所有檔案的類型
#!/bin/bash
for i in /var/* ;do
if [ -b $i ];then
echo "$i是塊裝置"
elif [ -c $i ] ;then
echo "$i是字元裝置"
elif [ -f $i ];then
echo "$i是普通檔案"
elif [ -h $i ];then
echo "$i是符号連結檔案"
elif [ -p $i ];then
echo "$i是管道檔案"
elif [ -S $i ];then
echo "$i是套接字檔案"
elif [ -d $i ];then
echo "$i是目錄檔案"
else
echo "檔案或目錄不存在"
fi
done
2、添加10個使用者user1-user10,密碼同使用者名
#!/bin/bash
#添加10個使用者
for i in user{1..10} ;do
id $i &> /dev/null && echo "$i 使用者已存在"|| (adduser $i ;echo "$i 使用者添加成功")
echo $i:$i | chpasswd
done
#!/bin/bash
#删除10個使用者
for i in user{1..10} ;do
id $i &> /dev/null && (userdel -fr $i ;echo "$i 删除成功") || echo "$i 删除失敗,該使用者肯不存在"
done
3、/etc/rc.d/rc3.d目錄下分别有多個以K開頭和以S開頭的 檔案;分别讀取每個檔案,以K開頭的檔案輸出為檔案加stop ,以S開頭的檔案輸出為檔案名加start; “K34filename stop” “S66filename start”
#!/bin/bash
for i in /etc/rc.d/rc3.d/[SK]* ;do
if [ $(basename $i | cut -c1) == "K" ] ;then
echo "`basename $i` stop"
else
echo "`basename $i` start"
fi
done
4、寫一個腳本,提示輸入正整數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"
5、寫一個腳本,提示請輸入網絡位址,如192.168.0.0,判 斷輸入的網段中主機線上狀态
#!/bin/bash
file=`mktemp /tmp/pingip.XXXXXX`
read -p "請輸入網絡位址 :" ip
i=`echo $ip | cut -d'.' -f1-3`
for z in {1..255};do
{
ip=$i.$z
ping -c1 -W1 $ip &> /dev/null && (echo "$ip is up" ) && echo ip >> $file
}&
done
sleep 1
echo "`cat $file | wc -l`線上"
rm -f $file &> /dev/null
6、列印九九乘法表
#!/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
6.2:while 循環
文法:
while CONDITION; do
循環體
done
CONDITION:循環控制條件;進入循環之前,先做一次判 斷;每一次循環之後會再次做判斷;條件為“true”,則執行 一次循環;直到條件測試狀态為“false”終止循環
是以:CONDTION一般應該有循環控制變量;而此變量的值會在循環體不斷地被修正
進入條件:CONDITION為true
退出條件:CONDITION為false
實戰訓練7
要求:用while實作
1、求100以内所有正整數之和
#!/bin/bash
sum=0
i=0
while [ $i -le 100 ] ;do
let sum+=$i
let i++
done
echo $sum
2、通過ping指令探測172.16.250.1-254範圍内的所有主機的線上狀态,統計線上主機和離線主機各多少。
#!/bin/bash
ip=10.1.250.
i=1
sum=0
while [ $i -lt 255 ] ;do
if ping -c1 -W1 $ip$i &> /dev/null ;then
let sum+=1
echo "$ip$i is up"
else
echo "$ip$i is down"
fi
let i+=1
done
echo "線上主機$sum台,離線$[255-sum]主機台"
3、列印九九乘法表
#!/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
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 "最大值是 $max ,最小值是 $min"
5、列印國際象棋棋盤
#!/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[47m \033[0m"
else
echo -en "\033[40m \033[0m"
fi
let y+=1
done
echo
let x+=1,y=1
done
#!/bin/bash
num=8
for((i=1;i<=$num;i++)){
for ((j=1;j<=$num;j++))
{
if [ $[(i+j)%2] -eq 0 ];then
echo -en "\033[47m \033[0m"
else
echo -en "\033[42m \033[0m"
fi
}
echo
}
6.3:until循環 (和while循環執行條件相反)
until CONDITION; do
循環體
done
進入條件: CONDITION 為false
退出條件: CONDITION 為true
6.4:循環控制語句continue,break
用于循環體中
continue [N]:提前結束第N層的本輪循環,而直接進入下一 輪判斷;最内層為第1層
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
continue
fi
CMDn
...
done
break [N]:提前結束第N層循環,最内層為第1層
while CONDTIITON1; do
CMD1
...
if CONDITION2; then
break
fi
CMDn
...
done
比如無限循環:
while true; do
循環體
done
until false; do
循環體
Done
實戰訓練8
1、每隔3秒鐘到系統上擷取已經登入的使用者的資訊;如果發 現使用者hacker登入,則将登入時間和主機記錄于日志 /var/log/login.log中,并提示該使用者退出系統
#!/bin/bash
username=cent
{
while true ;do
if who | egrep "^\b$username\b" &> /dev/null ;then
who | egrep "^\b$username\b" >> /var/log/login.log
echo "$username 已經登入"
echo "fuck ,go out my system" | write $username
else
echo "$username 已經下線"
fi
sleep 3
done
}
#!/bin/bash
username=hacker
exituser()
{
echo "fuck you,you will exit,haha" | write $username
sleep 2
pidlist=$(ps -f h -u $username | tr -s ' '|cut -d' ' -f2)
for i in $pidlist ;do
kill -9 $i
# echo "正在結束程序"
done
}
while true ;do
if w | egrep "^\b$username\b" &> /dev/null ;then
w | egrep "^\b$username\b" >> /var/login.log
echo "$username 已經登入"
exituser
else
echo "$username 已經下線"
fi
sleep 3
done
2、随機生成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,you are very clever"
break
fi
else
read -p "error,please input a number less than ten: " num
fi
done
6.5 一些特殊用法
while循環的特殊用法(周遊檔案的每一行):
while read line; do
循環體
done < /PATH/FROM/SOMEFILE
依次讀取/PATH/FROM/SOMEFILE檔案中的每一行,且将行指派給變量line
練習 掃描/etc/passwd檔案每一行,如發現GECOS字段為空,則填充使用者名和機關電話為62985600,并提示該使用者的GECOS資訊修改成功。
#!/bin/bash
phone=" phone number is 62985600"
pathname=/etc/passwd
while read line;do
name=`echo $line|cut -d: -f1`
b=`echo $line | cut -d: -f5|wc -c`
if [ $b -eq 1 ] ;then
chfn -f $name -p $phone $name &>/dev/null && echo "$name資訊修改成功" || echo "$name資訊修改失敗"
fi
done < $pathname
雙小括号方法,即((…))格式,也可以用于算術運算
雙小括号方法也可以使bash Shell實作C語言風格的變量操作 #I=10 #((I++))
for循環的特殊格式:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式)) do
循環體
done
控制變量初始化:僅在運作到循環代碼段時執行一次
控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算 ,而後再做條件判斷
6.6 select 循環與菜單
select variable in list
do
循環體指令
done
select 循環主要用于建立菜單,按數字順序排列的菜單項将顯示在标準錯誤上,并顯示PS3提示符等待使用者輸入
使用者輸入菜單清單中的某個數字,執行相應的指令
使用者輸入被儲存在内置變量REPLY中
select是個無限循環,是以要記住用break指令退出循環,或用exit指令終止腳本,也可以按Ctrl+c退出循環
select經常和case聯合使用
與for循環類似,可以省略in list,此時使用位置參數
比如
#!/bin/bash
PS3="please input your chose:"
list="start stop restart status exit"
select k in $list
do
case $k in
start)
echo start
;;
stop)
echo stop
;;
restart)
echo restart
;;
status)
echo status
;;
exit)
echo exit
;;
*)
break
;;
esac
done