小阿軒yx-Shell 編程之循環語句與函數

小阿軒yx-Shell 編程之循環語句與函數

for 循環語句

可以很好地解決順序編寫異常煩瑣、困難重重的全部代碼

(){}:里邊寫的都是命令

):不能嵌套

$():可以嵌套,適合更復雜的命令

命令執行的兩種方式

  • 交互式:在命令行里直接寫入命令,有多少需求就寫入多少次命令
  • 非交互式:把命令寫入到腳本里去執行,人就不用在腳本里敲命令

(注:交互:人與機器之間的一種交流)

# 不想看到消息提示就放到(&>/dev/null黑洞)里面
echo "123456" | passwd --stdin $uname &>/dev/null

?echo:作用回顯(將內容顯示到屏幕)

for 語句的結構

(注:for循環語句需要有一個取值列表)

for 變量名 in 取值列表 
do
命令序列 
done

?根據姓名列表批量添加用戶

# 創建用戶的列表文件
[root@localhost ~]# vim /root/users.txt
zhangsan
lisi
wangwu
# 編輯批量添加用戶的腳本
[root@localhost ~]# vim uaddfor.sh
#!/bin/bash
ULIST=$(cat /root/users.txt)
for UNAME in $ULIST
douseradd $UNAMEecho "123456" | passwd --stdin $UNAME &>/dev/null
done
給腳本賦予執行權限
[root@localhost ~]# chmod +x uaddfor.sh
# 測試并確認執行結果
[root@localhost ~]# ./uaddfor.sh
[root@localhost ~]# cat /etc/passwd

?編輯批量刪除用戶的腳本

[root@localhost ~]# vim udelfor.sh
#!/bin/bash
ULIST=$(cat /root/users.txt)
for UNAME in $ULIST
do# 不想看到消息提示就放到黑洞里userdel -r $UNAME &>/dev/nulldone
# 給腳本賦予執行權限
[root@localhost ~]# chmod a+x udelfor.sh
# 測試并確認執行結果
[root@localhost ~]# ./udelfor.sh
[root@localhost ~]# cat /etc/pwd

根據 IP 地址列表檢查主機狀態

# 創建IP地址列表文件
[root@localhost ~]# vim /root/ipadds.txt
172.16.1.1
172.16.1.111
172.16.1.222
192.168.10.10
# 編輯循環檢查各主機的腳本
[root@localhost ~]# vim chkhosts.sh
#!/bin/bash
HLIST=$(cat /root/ipadds.txt)
for IP in $HLIST
doping -c 3 -i 0.2 -W 3 $IP &> /dev/nullif [ $? -eq 0  ]thenecho "Host $IP is up."elseecho "Host $IP is down."fi
done
# 添加執行權限
[root@localhost ~]# chmod a+x chkhost.sh
# 測試并確認執行結果
[root@localhost ~]# bash chkhosts.sh
  • 需要指定一個變量及可能的取值列表

????????取值列表:稱為 for 語句的執行條件,其中包括多個屬性相同的對象,需要預先指定

  • 針對每個不同的取值重復執行相同的命令序列
  • 直到變量值用完退出循環從而不會進入死循環

使用 while 循環語句

可用于

  • 求控制循環次數
  • 操作對象按數字順序編號
  • 按特定條件執行重復操作

while 語句的結構

while 條件測試操作 
do 
命令序列 
done
# 批量添加用戶腳本
[root@localhost ~]# vim uaddwhile.sh
#!/bin/bash
PREFIX="stu"
i=1
while [ $i -le 20 ]
douseradd ${PREFIX}$iecho "123456" | passwd --stdin ${PREFIX}$i &> /dev/nulllet i++
done
# 添加執行權限
[root@localhost ~]# chmod a+x uaddwhile.sh
# 測試并確認執行結果
[root@localhost ~]# bash uaddwhile.sh 
[root@localhost ~]# grep "stu" /etc/passwd | tail -3或者#!/bin/bash
PREFIX="stu"
i=1
while [ $i -le 20 ]
douseradd ${PREFIX}$iecho "123456" | passwd --stdin ${PREFIX}$i &> /dev/nulli=`expr $i + 1`
done
# 批量刪除用戶腳本
[root@localhost ~]# vim udelwhile.sh
#!/bin/bash
PREFIX="stu"
i=1
while [ $i -le 20 ]
douserdel -r ${PREFIX}$ilet i++done
# 添加執行權限
[root@localhost ~]# chmod a+x udelwhile.sh
# 測試并確認執行結果
[root@localhost ~]# bash udelwhile.sh
id stu20

猜價格?

[root@localhost ~]# vim pricegame.sh
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TIMES=0
echo "商品實際價格范圍為0-999,猜猜看是多少?"
while true
doread -p "請輸入你猜測的價格數目:" INTlet TIMES++if [ $INT -eq $PRICE ] ; thenecho "恭喜你答對了,實際價格是 $PRICE"echo "你總共猜測了$TIMES 次"exit 0elif [ $INT -gt $PRICE  ] ; thenecho "太高了!"elseecho "太低了!"fi
done

(?注:linux中隨機數的取值范圍是0--32767,和什么數取余,取余后的最大數就是誰,不包含該數字)

# 添加執行權限
[root@localhost ~]# chmod a+x pricegame.sh
# 測試并確認執行結果
[root@localhost ~]# bash pricegame.sh
  • 不需要取值列表
  • 可以根據特定的條件反復執行一個命令序列,直到該條件不再滿足時為止。
  • 在腳本應用中,要避免出現死循環的情況,否則后邊的命令操作將無法執行。
  • 因此,循環體內的命令序列中應包括修改測試條件的語句,以便在適當的時候使測試條件不再成立,從而結束循環
while 循環語句的兩個結果(只有兩個)
  • true(真)
  • false(假)

用 true 作為條件時

  • 表示條件永遠成立,循環體內的命令序列將無限執行下去,除非強制終止腳本(或通過 exit 語句退出腳本)

反之用 false 作為條件

  • 則循環體將不會被執行

(注:這兩個特殊條件也可以用在 if 語句的條件測試中)

until 循環語句

直到性循環

(注:一般處理一些有特色的)

until 循環語句的結構

until 條件測試操作 
do 
done

案例一

[root@localhost ~]# vim until_v1.sh 
#!/bin/bash 
i=0;s=0 
until [ $i -eq 50 ] 
do 
let "i=$i+1";let "s=$s+$i" 
done 
echo 'sum(1..50)='$s# 添加執行權限
[root@localhost ~]# chmod +x sum1to50_until_v1.sh# 測試結果
[root@localhost ~]# bash sum1to50_until_v1.sh 

?案例二

[root@localhost ~]# vim until_v2.sh 
var1=100
until [ $var1 -eq 0 ]
doecho $var1var1=$[ $var1 - 25 ]
done# 添加執行權限
[root@localhost ~]# chmod +x until_v2.sh# 測試結果
[root@localhost ~]# bash until_v2.sh
  • 與 while 循環類似
  • while 循環能實現的腳本 until 同樣也可以實現
區別
  • while 循環在條件為真時繼續執行循環
  • 而 until 則是在條件為假時執行循環

Shell 函數

代碼的重用

local:作用將變量設置為局部變量

函數的用法

案例一

[function] 函數名() { 
[return x] 
} 
[root@localhost ~]# cat exa1.sh 
#!/bin/bash
zhangsan() {echo "my name is zhangsan"
}lisi() {echo "my name is lisi"
}zhangsan
lisi
# 測試結果
[root@localhost ~]# bash exa1.sh

案例二?

[root@localhost ~]# cat exa2.sh 
#!/bin/bash
name() {echo "my name is $1"
}
name $1
# 測試結果
[root@localhost ~]# bash exa2.sh zhangsan
my name is zhangsan
[root@localhost ~]# bash exa2.sh lisi
my name is lisi

案例四?

[root@localhost ~]# vim fun_scope.sh 
myfun () 
{ local i i=8 echo $i 
}
i=9 
myfun 
echo $i
# 添加執行權限
[root@localhost ~]# chmod +x fun_scope.sh 
# 測試結果
[root@localhost ~]# bash fun_scope.sh

(注:通過內置命令 local 將變量的值限定在函數內部)

Shell 腳本執行的過程中

  • 函數被置于內存中
  • 每次調用函數時不需要從硬盤讀取,因此運行的速度比較快

Shell 編程中函數并非是必須的元素

使用函數的好處

  • 可以對程序進行更好的組織
  • 將一些相對獨立的代碼變成函數
  • 可以提高程序可讀性與重用性
  • 避免編寫大量重復代碼
  • “function”關鍵字表示定義一個函數,可以省略;
  • “{”符號表示函數執行命令的入口,該符號可以與函數名同行也可以在函數名下一行的句首;
  • “}”符號表示函數體結束,兩個大括號之間{ }是函數體;
  • “命令序列”部分可以是任意的 Shell 命令,也可以調用其他函數;
  • “return”表示退出函數返回一個退出值,通過返回值判斷執行是否成功,也可以使用 exit 終止整個 Shell 腳本

Shell 函數調用的方法為

函數名 [參數 1] [參數 2]

函數變量的作用范圍

  • Shell 腳本中函數的執行不會開啟一個新的子 Shell,而是僅在當前定義的 Shell環境中有效
  • 如果 Shell 腳本中的變量沒有經過特殊設定,默認在整個腳本中都是有效的
  • 編寫腳本時,有時需要將變量的值限定在函數內部,可以通過內置命令 local 來實現
  • 函數內部變量的使用,可以避免函數內外同時出現同名變量對腳本結果的影響

函數的參數

  • 在使用函數參數時,函數名稱在前參數在后,函數名和參數之間用空格分隔,可以有多個參數,參數使用$1、$2、$3……的方式表示
  • 以此類推,從第 10 個參數開始,調用方法為${10},不加大括號無法調用成功

遞歸函數

遞歸算法的經典例子是計算階乘

案例

[root@localhost ~]# vim fun_recursion.sh
#!/bin/bash 
function factorial { if [ $1 -eq 1 ] then echo 1 else local temp=$[ $1 - 1 ] local result=$(factorial $temp) echo $[ $result * $1 ] fi
} read -p "Enter value: " value 
result=$(factorial $value) 
echo "The factorial of $value is: $result"
# 測試結果
[root@localhost ~]# bash fun_recursion.sh

調用自己本身的函數實現遞歸函數

Linux 系統上編寫 Shell腳本的時候,經常需要遞歸遍歷系統的目錄,列出目錄下的文件和目錄,逐層遞歸列出,并對這些層級關系進行展示

Shell 數組

Shell 腳本中,數組是一種常見的數據結構

主要的應用場景包括

數組常用定義方法包括以下幾種

方法一

數組名=(value0 value1 value2 ...)

方法二

數組名=([0]=value [1]=value [2]=value ...)

方法三

列表名=”value0 value1 value2 ...” 
數組名=($列表名)

方法四

數組名[0]=”value” 
數組名[1]=”value” 
數組名[2]=”value”
......

獲取數組的長度?

[root@localhost ~]# arr_number=(1 2 3 4 5) 
[root@localhost ~]# arr_length=${#arr_number[*]} 
[root@localhost ~]# echo $arr_length 
5
[root@localhost ~]# arr_length_1=${#arr_number[@]}
[root@localhost ~]# echo $arr_length_1
5

讀取某下標賦值

[root@localhost ~]# arr_index2=${arr_number[2]} 
或
[root@localhost ~]# echo ${arr_number[2]} 
//第三個元素 
[root@localhost ~]# echo $arr_index2 
3或
echo ${aaa[3]}

數組遍歷?

[root@localhost ~]# vim array_traverse.sh 
#!/bin/bash 
arr_number=(1 2 3 4 5) 
for v in ${arr_number[@]} 
do
echo $v 
done
# 添加執行權限
[root@localhost ~]# chmod +x array_traverse.sh
# 測試結果
[root@localhost ~]# bash array_traverse.sh

數組切片?

[root@centos-7 ~]# arr=(1 2 3 4 5)
//輸出整個數組 
[root@centos-7 ~]# echo ${arr[@]} 
1 2 3 4 5
//${數組名[@或*]:起始位置:長度} 
[root@centos-7 ~]# echo ${arr[@]:0:2}
1 2 
[root@centos-7 ~]# echo ${arr[@]:2:3} 
3 4 5 

數組替換?

[root@centos-7 ~]# arr=(1 2 3 4 5)
// ${數組名[@或*]/查找字符/替換字符} 
[root@centos-7 ~]# echo ${arr[@]/4/66}
1 2 3 66 5
// 并不會替換數組原有內容 
[root@centos-7 ~]# echo ${arr[@]} 
1 2 3 4 5
// 要實現改變原有數組,可通過重新賦值實現 
[root@centos-7 ~]# arr=(${arr[@]/4/66}) 
[root@centos-7 ~]# echo ${arr[@]} 
1 2 3 66 5

數組刪除?

[root@centos-7 ~]# arr=(1 2 3 4 5) 
[root@centos-7 ~]# unset arr
// 刪除數組 
[root@centos-7 ~]# echo ${arr[*]} 
[root@centos-7 ~]# arr=(1 2 3 4 5) 
[root@centos-7 ~]# unset arr[2] 
// 刪除第三個元素 
[root@centos-7 ~]# echo ${arr[*]} 
1 2 4 5

(注:$* 和 $@ 都表示傳遞給函數或腳本的所有參數)

區別

  • $* 和 $@ 不被雙引號" "包圍時,它們之間沒有任何區別,都是將接收到的每個參數看做一份數據,彼此之間以空格來分隔

被雙引號" "包含時,就會有區別

"? " 會 將 所 有 的 參 數 從 整 體 上 看 做 一 份 數 據 , 而 不 是 把 每 個 參 數 都 看 做 一 份 數 據?

"@"仍然將每個參數都看作一份數據,彼此之間是獨立的

Shell 腳本調試

[root@localhost ~]# vim aaa.sh #!/bin/bash 
set -x 
##開啟調試模式 read -p "請輸入您的分數(0-100):" GRADE 
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] then echo "$GRADE 分!優秀" 
set +x 
##關閉調試模式 elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] thenecho "$GRADE 分,合格" 
else echo "$GRADE 分?不合格" 
fi
  • 把復雜的腳本簡單化
  • 要思路清晰
  • 分段實現

(注:執行腳本時出現錯誤后,不要只看提示的錯誤行,要觀察整個相關的代碼段)

為避免編寫的腳本出錯,除了在編寫腳本時注意書寫規范,排除語法錯誤,更重要的是利用調試腳本工具來調試腳本。

echo 命令是最有用的調試腳本工具之一,一般在可能出現問題的腳本中加入 echo 命令,采用的是分段排查的方式

(注:除了 echo 命令之外,bash Shell 也有相應參數可以調試腳本)

常用參數的具體含義為

  • -n:不會執行該腳本,僅查詢腳本語法是否有問題,如果沒有語法問題就不顯示任何內容,如果有問題會提示報錯
  • -v:在執行腳本時,先將腳本的內容輸出到屏幕上然后執行腳本,如果有錯誤,也會給出錯誤提示
  • -x:將執行的腳本內容輸出到屏幕上,這個是對調試很有用的參數

?小阿軒yx-Shell 編程之循環語句與函數

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/18271.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18271.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18271.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

day42 62.不同路徑 63. 不同路徑 II

62.不同路徑 思路 機器人從(0 , 0) 位置出發,到(m - 1, n - 1)終點。 按照動規五部曲來分析: 1.確定dp數組(dp table)以及下標的含義 dp[i][j] :表示從(0 ,0)出發,…

2-Django項目進階--繼續學生管理系統

目錄 項目框架: urls.py views.py modules.py class_data.html add_and_modify.html add_stu.html 筆記: 繼承語法 模板繼承總結: 班級添加 add_and_modify.html 修改添加公用一個頁面即可 views.py 班級修改 views.py url.py 班級刪除 views.py…

boost asio異步服務器(2)實現偽閉包延長連接生命周期

閉包 在函數內部實現一個子函數,子函數的作用域內能訪問外部函數的局部變量。閉包就是能夠讀取其他函數內部變量。但是由于閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成程的性能問題&#x…

構造器--5.28

不用一個個屬性賦值的方法: 知道了類的創建與使用,但是每次賦值都是一個個調用,我們可以用構造器使得方法簡單一點,不用一個個調用屬性賦值,直接傳參就OK了; 點擊類名然后ctrl可以查看構造器 public yanxi…

C++完成特色旅游管理信息系統

背景: 繼C完成淄博燒烤節管理系統后,我們來到了特色旅游管理信息系統的代碼編寫,歷史鏈接點下方。 C完成淄博燒烤節管理系統_淄博燒烤總賬管理系統的-CSDN博客 問題描述: 為了更好的管理各個服務小組,開發相應的管…

民國漫畫雜志《時代漫畫》第30期.PDF

時代漫畫30.PDF: https://url03.ctfile.com/f/1779803-1248635414-87c8c8?p9586 (訪問密碼: 9586) 《時代漫畫》的雜志在1934年誕生了,截止1937年6月戰爭來臨被迫停刊共發行了39期。 ps: 資源來源網絡!

webpack打包配置項

webpack打包配置項 在config.js 中 module.exports {publicPath: process.env.NODE_ENV production ? / : /, //靜態資源目錄outputDir: dist, //打包名稱assetsDir: static,//靜態資源,目錄devServer: {port: port,open: false,overlay: {warnings: false,erro…

SpringBoot自動裝配源碼

自動裝配: 實際上就是如何將Bean自動化裝載到IOC容器中管理,Springboot 的自動裝配時通過SPI 的方式來實現的 SPI:SpringBoot 定義的一套接口規范,這套規范規定:Springboot 在啟動時會掃描外部引用 jar 包中的META-IN…

css 漸變色邊框

效果圖&#xff1a; 代碼&#xff1a; <style>:root{--br-radius: 12px;}.list{position: relative;}.list_tle{margin-top: 15px;margin-bottom: 5px;}.item{position: relative;display: inline-flex;} .br1 {padding: 10px 16px;clip-path: inset(0 round 6px);borde…

官宣|HelpLook現已入駐釘釘應用市場,助力企業知識管理知識

前一陣子OpenAI公司最新的GPT-4o技術震撼發布&#xff0c;人工智能的實際應用前景再次引起行業矚目&#xff0c;或者被GPT4o的數據分析等特色功能折服。如您正尋求將AI技術融入企業知識管理&#xff0c;不要錯過HelpLook&#xff01;HelpLook AI知識庫已經正式入駐釘釘應用市場…

Flutter 中的 SlideTransition 小部件:全面指南

Flutter 中的 SlideTransition 小部件&#xff1a;全面指南 在 Flutter 中&#xff0c;SlideTransition 是一個動畫組件&#xff0c;用于創建滑動動畫效果&#xff0c;使得子組件可以沿著一個軸滑動進入或滑動退出視圖。這種動畫效果常用于頁面轉場、菜單展開收起、元素的添加…

2024-5-8——給植物澆水

2024-5-8 題目來源我的題解方法一 模擬 題目來源 力扣每日一題&#xff1b;題序&#xff1a;2079 我的題解 方法一 模擬 依次模擬澆水動作 使用一個變量 cap維護剩余的水量&#xff0c;使用t作為還未澆水的樹的下標。當從第 i?1株植物到達第 i株植物時&#xff1a; 如果 ca…

前端中css穿透樣式:deep的用法

在前端開發中&#xff0c;尤其是使用 Vue.js 這樣的框架時&#xff0c;有時我們需要在子組件中修改或影響由父組件傳遞下來的樣式。然而&#xff0c;由于組件的封裝和樣式隔離&#xff0c;直接修改子組件中的樣式可能不起作用。這時&#xff0c;我們可以使用 ::v-deep 偽元素來…

基于Android的家庭理財APP的設計與實現(論文+源碼)_kaic

摘 要 隨著我國居民收入和生活水平的提高&#xff0c;家庭理財成為人們熱議的焦點問題。在需求分析階段&#xff0c;系統從用戶的實際需求出發&#xff0c;確定了用戶賬戶管理、記賬、數據分析和提醒功能等幾個核心需求。用戶賬戶管理包括用戶注冊、登錄和密碼找回等基本操作…

【4th chapter】信息安全技術—安全技術、安全架構、安全策略、安全管理、軟件的脆弱性

概要 安全技術安全架構安全策略安全管理軟件的脆弱性加密技術&#xff08;Encryption Technology&#xff09;安全域架構&#xff08;Security Domain Architecture&#xff09;訪問控制策略&#xff08;Access Control Policy&#xff09;信息安全管理體系&#xff08;Inform…

面試數據庫八股文十問十答第六期

面試數據庫八股文十問十答第六期 作者&#xff1a;程序員小白條&#xff0c;個人博客 相信看了本文后&#xff0c;對你的面試是有一定幫助的&#xff01;關注專欄后就能收到持續更新&#xff01; ?點贊?收藏?不迷路&#xff01;? 1&#xff09;來說說一條 SQL 語句的執行…

leetcode題目238

除自身以外的數組的乘積 中等 給你一個整數數組 nums&#xff0c;返回 數組 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘積 。 題目數據 保證 數組 nums之中任意元素的全部前綴元素和后綴的乘積都在 32 位 整數范圍內。 請 不要使用除法&…

大數據技術Hbase列數據庫——topic1

目錄 搭建單機版Hbase驗證方法一驗證方法二 搭建單機版Hbase 驗證方法一 使用 jps 命令查看 HMaster 進程是否啟動 首先使用xftp 7上傳hbase-2.1.0安裝壓縮包到虛擬機進行解壓縮到某一地址&#xff0c;這里解壓縮到了上傳的路徑即/root/software/ tar -zxvf hbase-2.1.0-bi…

進程與線程學習

多線程 tthreading.Thread(targettask,arge(11,)) start&#xff08;&#xff09;開始 join&#xff08;&#xff09;等待 主線程在默認情況下會等待所有非守護線程&#xff08;子線程&#xff09;結束后才會結束程序。也就是說&#xff0c;如果主線程在結束前沒有調用所有…

2025第十屆美陳展

展位又遭瘋搶&#xff01;2025第十屆美陳展釋放“無界之美” 美是全球通用的語言&#xff0c;人類對美的追求始終如一&#xff0c;大眾審美在經歷了時代的變遷后開始趨同&#xff0c;東方文明深處的美學經濟開始崛起。 在如今商業邁入存量階段&#xff0c;以品牌為突破口打造…