理論+實驗·Shell程式設計之循環語句、函數、數組
文章目錄
- 理論+實驗·Shell程式設計之循環語句、函數、數組
-
- for語句的結構
-
-
- 讀取不通的變量值,用來逐個執行同一組指令
-
- for語句應用執行個體
-
-
- 示例一
- 示例二
-
- while語句的結構
-
-
- 重複測試某個條件,隻要條件成立則反複執行
-
- while語句應用執行個體
-
-
- 示例一
- 示例二
- 雙重循環示例
-
- until語句的結構
-
-
- 重複測試某個條件,隻要條件不成立則反複執行
-
- until語句應用執行個體
-
-
- 示例一
- 示例二
-
- Shell函數
-
-
- 将指令序列按格式寫在一起
- 可友善重複使用指令序列
- Shell函數定義
- 調用函數的方法
-
- 函數應用執行個體
-
-
- 示例一
- 示例二
-
- 函數的作用範圍
-
-
- 函數在Shell腳本中僅在目前Shell環境中有效
- Shell腳本中變量預設全局有效
- 将變量限定在函數内部使用local指令
- 示例
-
- 函數的參數
-
-
- 參數的用法
- 參數的表示方法
- 示例
-
- 遞歸函數
-
-
- 調用自己本身的函數
- 示例
-
- Shell數組
-
-
- 應用場景包括
- 數組定義方法
- 數組包括的資料類型
-
- Shellt數組操作
-
-
- 擷取數組長度
- 讀取某下标指派
- 數組周遊
- 示例
- 數組切片
- 數組的替換
- 數組删除
- 示例
-
- Shell腳本調試
-
-
- echo指令
- bash指令
- set指令
-
for語句的結構
讀取不通的變量值,用來逐個執行同一組指令
for 變量名 in 取值清單 ===>變量名是臨時變量名從取值清單裡面去讀
do
指令序列
done
for語句應用執行個體
示例一
批量添加使用者
使用者名存放在user.txt檔案中,每行一個
初始化密碼均設為123456
驗證腳本
#!/bin/bash
#定義集合
list=`cat /opt/users.txt`
#周遊建立新使用者
for user in $list
do
#建立新使用者
useradd $user
#設定密碼
echo "123456" | passwd --stdin $user
echo "$user建立成功"
done
示例二
根據IP位址檢查主機狀态
IP位址存放在ipadds.txt檔案中,每行一個
使用ping指令檢測各主機的連通性
#!/bin/bash
#定義集合
ip_=`cat /opt/ipadds.txt`
#周遊
for ipaddress in $ip_
do
#pingIP位址
ping -c 3 -i 0.2 -W 3 $ipaddress &>/dev/null ===>-c 次數 -i 間隔多久在ping一次 -W 等待時間
if [ $? -eq 0 ];then
echo "${ipaddress} is up"
else echo "${ipaddress} is down"
fi
done
常用變量
變量i=1
i<=10
i++ 自身加1
((;;)) ===>沒有條件無限循環
break ===>退出目前循環
exit 0 ===>退出應用程式,後面的所有語句都不會執行
exit 0 ===>0是狀态碼 0 表示正常退出
(1-100)偶數和
#!/bin/bash
sum=0
for ((i=1;i<=100;i++))
do
#條件篩選
if [ `expr $i % 2` -eq 1 ];then
let sum=${sum}+${i}
fi
done
echo "${sum}"
(1-100)奇數和
#!/bin/bash
sum=0
for ((i=1;i<=100;i+=2))
do
let sum+=$i
done
echo "$sum"
++ ===>自身變量+1
-- ===>自身變量-1 let可以單獨使用
+=5 ===>自身變量+5
-=5 ===>自身變量*5
\*=5 ===>自身變量乘以5
/=5 ===>自身變量除以5
%=5 ===>自身變量%5
((;;)) 無限循環
$() ===> `` 指令替換
[ ] ===>test 條件判斷
$[ ] ===> $(( )) 算術運算
${} 變量替換
(()) ===> 支援數學運算符的 條件判斷
while語句的結構
重複測試某個條件,隻要條件成立則反複執行
while 條件測試操作
do
指令序列
done
隻要成立會一直不停的執行下去
while語句應用執行個體
示例一
批量添加使用者
使用者名稱以stu開頭,按數組順序進行編号
一共添加20各使用者,即stu1,stu2,stu3…stu20
從初始密碼均設為123456
#!/bin/bash
i=1
user=stu$i
while [ $i -le 20 ]
do
echo stu$i
useradd stu$i
echo "123456" | passwd --stdin $user
echo "使用者${user}輸出成功"
let i++
done
示例二
猜商品價格遊戲
通過變量RANDOM獲得随機數
提示使用者猜測并記錄次數,猜中後退出循環
#!/bin/bash
#假設商品價格為60元
read -p "請猜出商品的價格(元):" howmuch
while [ $howmuch -ne 60 ];do
echo "離商品價格還有一點距離"
read -p "請重新猜出商品的價格(元):" howmuch
done
echo "恭喜您猜對了,商品價格為$howmuch"
coutinue 跳過本次continue以下執行語句直接進入下一次循環
break 退出目前循環語句
exit 1 直接退出不執行下面的語句
雙重循環示例
九九乘法口訣表
#!/bin/bash
i=1
while [ $i -le 9 ]
do
j=1
while [ $j -le $i ]
do
echo -n "${i}*${j}"="`expr ${i} \* ${j}` "
let j++
done
echo ""
let i++
done
等腰三角形
#!/bin/bash
read -p "請輸入行數:" num
i=1
while [ $i -le $num ]
do
j=${num}
while [ $j -ge $i ]
do
echo -n " "
let j--
done
k=1
while [ $k -le $i ]
do
echo -n "* "
let k++
done
echo ""
let i++
done
until語句的結構
重複測試某個條件,隻要條件不成立則反複執行
until 條件測試操作
do
指令序列
done
until語句應用執行個體
示例一
計算1~50的和值
通過循環累加的方式計算1-50的和值
#!/bin/bash
i=1
sum=0
until [ $i -eq 51 ]
do
\#echo $i
let sum+=$i
let i++
done
echo "和為:$sum"
示例二
為指定使用者發送線上消息
若使用者不線上(未登入系統),則每10分鐘試一次,直至使用者登入系統後在發送資訊
使用者名與資訊通過位置參數傳遞給腳本
#!/bin/bash
username=$1
#格式參數不能為空
if [ $# -lt 1 ];then
echo "Usage:'basename $0' <username> [<message>]"
exit 1
fi
#驗證是否屬于系統使用者
if grep "^$username" /etc/passwd > /dev/null;then空格:
else
echo "not user"
exit 2
fi
#測試使用者是否線上,如果不線上,每5秒聯系一次
until who | grep "$username" > /dev/null;do
echo "user not login"
sleep 5
done
#發送消息
echo "$2" | write "$username"
echo "${username}發送成功"
Shell函數
将指令序列按格式寫在一起
可友善重複使用指令序列
Shell函數定義
[ function ] 函數名(){
指令序列
[return x] ===>傳回的狀态碼 $?
傳回資料 echo輸出
}
調用函數的方法
函數名 [參數1] [參數2]
函數應用執行個體
示例一
兩個數字求和
通過sum (){} 定義函數
使用read指令互動輸入兩個數并求和
#!/bin/bash
function sum(){
#指令序列
read -p "請輸入第一個整數:" num1
read -p "請輸入第二個整數:" num2
SUM=$[${num1}+${num2}]
#echo傳回的是處理結果值
echo "和為:$SUM"
#return傳回的是狀态碼
return 100
}
sum
示例二
編寫登入系統後便可使用的使用者自定義函數
編輯使用者自定義函數檔案/root/function
在目前Shelll中加載可執行的函數檔案/root/function
在~/.bashrc檔案中添加source /root/function指令
[[email protected] opt]# vim /root/.bashrc
......
function sum(){
#指令序列
read -p "請輸入第一個整數:" num1
read -p "請輸入第二個整數:" num2
SUM=$[${num1}+${num2}]
#echo傳回的是處理結果值
echo "和為:$SUM"
#return傳回的是狀态碼
return 100
}
[[email protected] opt]# source /root/.bashrc ===>重新加載以下配置檔案
[[email protected] opt]# sum ===>直接調用
函數的作用範圍
函數在Shell腳本中僅在目前Shell環境中有效
Shell腳本中變量預設全局有效
将變量限定在函數内部使用local指令
示例
函數内部變量通過local來實作
通過定義myfun函數,在其内部設定局部變量i
函數内部和外部分别指派,進行結果驗證
local score ===>加了local就是局部變量
函數的參數
參數的用法
函數名稱參數1參數2多數…
參數的表示方法
$1 $2 $3… S(10} ${11} …
示例
通過函數參數将日志資訊寫入檔案,
通過定義appendfile函數實作
遞歸函數
調用自己本身的函數
示例
遞歸周遊目錄
通過定義遞歸函數list_files來實作
#!/bin/bash
function list_files(){
for f in `ls $1`
do
if [ -d "$1/$f" ];then
echo "$2$f"
#遞歸調用
list_files "$1/$f" " $2"
else
echo "$2$f"
fi
done
}
list_files "/var/log" ""
Shell數組
應用場景包括
擷取數組長度
擷取元素長度
周遊元素
元素切片 ===>某一個子部份
元素替換
元素删除
…
數組定義方法
方法一
數組名= (value0 value1 value2 ...)
方法二
數組名= ([0]=value [1]=value [2]=value ...)
方法三
清單名="value0 value1 value2"
數組名=($清單名)
方法四
數組名[0]="value"
數組名[1]="value"
數組名[2]="value"
數組包括的資料類型
數值類型
字元類型
使用""或’'定義
#!/bin/bash
#建立存放(1-100)奇數的數組
for ((i=0,j=1;i<=99,j<=100;i++,j+=2))
do
arr[$i]="$j"
done
echo ${arr[*]}
#!/bin/bash
#建立任意數字及長度的數組,根據客戶的需求加入元素
i=0
while [ $i -ge 0 ]
do
read -p "請輸入該數組的元素:" num
arr[$i]="$num"
let i++
if [ -z $num ];then
echo ${arr[*]}
exit 1
fi
done
Shellt數組操作
擷取數組長度
$(數組名[@/]}
[[email protected] -# arr-number=(1 2 3 4 5);
[[email protected] -arr-length=$(#arr-number[*]}
[email protected] -]# echo $arr_length
5
讀取某下标指派
$(數組名[下表])
[[email protected]$(arr-number[2])
[[email protected]# echo $arr-index2
3
數組周遊
[[email protected] ~] # for v in $farr numberl@}
>do
>echo $v
> done
1
2
3
4
5
示例
#!/bin/bash
#不滿足60分的都加到60分
score=(66 58 49 60 88 96)
for ((i=0;i<=&{#score[*]};i++));do
if [ ${score[$i]} -lt 60 ];then
new[$i]=60
else
new[$i]=${score[$i]}
fi
done
echo ${new[*]}
#!/bin/bash
#顯示出最大的那個分數
score=(66 58 49 60 88 96)
tmp=0
for ((i=0;i<${#score[*]};i++));do
if [ ${score[$i]} -gt $tmp ];then
tmp=${score[$i]}
fi
done
echo $tmp
#!/bin/bash
#将分數從大到小排序
arr=(85 100 56 69 75 98 65 45)
for ((i=0;i<${#arr[*]};i++))
do
for ((j=$i+1;j<${#arr[*]};j++))
do
if [ ${arr[$i]} -lt ${arr[$j]} ];then
tmp=${arr[$i]}
arr[$i]=${arr[$j]}
arr[$j]=$tmp
fi
done
done
echo ${arr[*]}
數組切片
${數組名[@或*]:起始位置:長度}
[[email protected]# arr=(1 2 3 4 5)
[[email protected]]# echo $farr[@])
1 2 3 4 5
[[email protected]]# echo $farr[@]:0:2}
1 2
[email protected] - echo $arr[@]:2:3}
3 4 5
數組的替換
${數組名[@或*]/查找字元/替換字元}
[[email protected] -]#arr=(1 2 3 4 5)
[[email protected]]# echo ${arr[@14/66}
12 3 66 5
[[email protected]]#echo $farr@])
1 2 3 4 5
[[email protected]# arr=($(arr[@]/4/66})
[[email protected] -]# echo $farr[@])
1 2 3 66 5
數組删除
unset
[[email protected] -# arr=(1 2 3 4 5)
[[email protected]~#unset arr
[[email protected] -]# echo ${arr[*])
[[email protected] arr=(1 2 3 4 5)
[[email protected]#unset arr[2)
[[email protected]]# echo ${arr[*])
1 2 4 5
示例
#!/bin/bash
#将低于60分以下的成績删除
score=(10 20 30 40 50 90 80 50 60)
i=1
for f in ${score[*]};do
if [ $f -lt 60 ];then
unset score[$i]
fi
lei i++
done
echo ${score[*]}
Shell腳本調試
echo指令
bash指令
指令文法
sh [-nvx] 腳本名
set指令
set -x:開啟調節模式
set +x:關閉調節模式