天天看點

理論+實驗·Shell程式設計之循環語句、函數、數組理論+實驗·Shell程式設計之循環語句、函數、數組

理論+實驗·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:關閉調節模式

繼續閱讀