這篇文章主要介紹怎么用Bash編程實(shí)現(xiàn)循環(huán),文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、外貿(mào)營(yíng)銷(xiāo)網(wǎng)站建設(shè),成都做網(wǎng)站公司-創(chuàng)新互聯(lián)建站已向成百上千家企業(yè)提供了,網(wǎng)站設(shè)計(jì),網(wǎng)站制作,網(wǎng)絡(luò)營(yíng)銷(xiāo)等服務(wù)!設(shè)計(jì)與技術(shù)結(jié)合,多年網(wǎng)站推廣經(jīng)驗(yàn),合理的價(jià)格為您打造企業(yè)品質(zhì)網(wǎng)站。
我使用過(guò)的所有編程語(yǔ)言都至少有兩種循環(huán)結(jié)構(gòu)來(lái)用來(lái)執(zhí)行重復(fù)的操作。我經(jīng)常使用 for
循環(huán),然而我發(fā)現(xiàn) while
和 until
循環(huán)也很有用處。
我的理解是,在 bash 中實(shí)現(xiàn)的 for
命令比大部分語(yǔ)言靈活,因?yàn)樗梢蕴幚矸菙?shù)字的值;與之形成對(duì)比的是,諸如標(biāo)準(zhǔn) C 語(yǔ)言的 for
循環(huán)只能處理數(shù)字類(lèi)型的值。
Bash 版的 for
命令基本的結(jié)構(gòu)很簡(jiǎn)單:
for Var in list1 ; do list2 ; done
解釋一下:“對(duì)于 list1
中的每一個(gè)值,把 $Var
設(shè)置為那個(gè)值,使用該值執(zhí)行 list2
中的程序語(yǔ)句;list1
中的值都執(zhí)行完后,整個(gè)循環(huán)結(jié)束,退出循環(huán)?!?list1
中的值可以是一個(gè)簡(jiǎn)單的顯式字符串值,也可以是一個(gè)命令執(zhí)行后的結(jié)果(`` 包含其內(nèi)的命令執(zhí)行的結(jié)果,本系列第二篇文章中有描述)。我經(jīng)常使用這種結(jié)構(gòu)。
要測(cè)試它,確認(rèn) ~/testdir
仍然是當(dāng)前的工作目錄(PWD)。刪除目錄下所有東西,來(lái)看下這個(gè)顯式寫(xiě)出值列表的 for
循環(huán)的簡(jiǎn)單的示例。這個(gè)列表混合了字母和數(shù)字 — 但是不要忘了,在 bash 中所有的變量都是字符串或者可以被當(dāng)成字符串來(lái)處理。
[student@studentvm1 testdir]$ rm *[student@studentvm1 testdir]$ for I in a b c d 1 2 3 4 ; do echo $I ; doneabcd1234
給變量賦予更有意義的名字,變成前面版本的進(jìn)階版:
[student@studentvm1 testdir]$ for Dept in "Human Resources" Sales Finance "Information Technology" Engineering Administration Research ; do echo "Department $Dept" ; doneDepartment Human ResourcesDepartment SalesDepartment FinanceDepartment Information TechnologyDepartment EngineeringDepartment AdministrationDepartment Research
創(chuàng)建幾個(gè)目錄(創(chuàng)建時(shí)顯示一些處理信息):
[student@studentvm1 testdir]$ for Dept in "Human Resources" Sales Finance "Information Technology" Engineering Administration Research ; do echo "Working on Department $Dept" ; mkdir "$Dept" ; doneWorking on Department Human ResourcesWorking on Department SalesWorking on Department FinanceWorking on Department Information TechnologyWorking on Department EngineeringWorking on Department AdministrationWorking on Department Research[student@studentvm1 testdir]$ lltotal 28drwxrwxr-x 2 student student 4096 Apr 8 15:45 Administrationdrwxrwxr-x 2 student student 4096 Apr 8 15:45 Engineeringdrwxrwxr-x 2 student student 4096 Apr 8 15:45 Financedrwxrwxr-x 2 student student 4096 Apr 8 15:45 'Human Resources'drwxrwxr-x 2 student student 4096 Apr 8 15:45 'Information Technology'drwxrwxr-x 2 student student 4096 Apr 8 15:45 Researchdrwxrwxr-x 2 student student 4096 Apr 8 15:45 Sales
在 mkdir
語(yǔ)句中 $Dept
變量必須用引號(hào)包裹起來(lái);否則名字中間有空格(如 Information Technology
)會(huì)被當(dāng)做兩個(gè)獨(dú)立的目錄處理。我一直信奉的一條實(shí)踐規(guī)則:所有的文件和目錄都應(yīng)該為一個(gè)單詞(中間沒(méi)有空格)。雖然大部分現(xiàn)代的操作系統(tǒng)可以處理名字中間有空格的情況,但是系統(tǒng)管理員需要花費(fèi)額外的精力去確保腳本和 CLI 程序能正確處理這些特例。(即使它們很煩人,也務(wù)必考慮它們,因?yàn)槟阌肋h(yuǎn)不知道將擁有哪些文件。)
再次刪除 ~/testdir
下的所有東西 — 再運(yùn)行一次下面的命令:
[student@studentvm1 testdir]$ rm -rf * ; lltotal 0[student@studentvm1 testdir]$ for Dept in Human-Resources Sales Finance Information-Technology Engineering Administration Research ; do echo "Working on Department $Dept" ; mkdir "$Dept" ; doneWorking on Department Human-ResourcesWorking on Department SalesWorking on Department FinanceWorking on Department Information-TechnologyWorking on Department EngineeringWorking on Department AdministrationWorking on Department Research[student@studentvm1 testdir]$ lltotal 28drwxrwxr-x 2 student student 4096 Apr 8 15:52 Administrationdrwxrwxr-x 2 student student 4096 Apr 8 15:52 Engineeringdrwxrwxr-x 2 student student 4096 Apr 8 15:52 Financedrwxrwxr-x 2 student student 4096 Apr 8 15:52 Human-Resourcesdrwxrwxr-x 2 student student 4096 Apr 8 15:52 Information-Technologydrwxrwxr-x 2 student student 4096 Apr 8 15:52 Researchdrwxrwxr-x 2 student student 4096 Apr 8 15:52 Sales
假設(shè)現(xiàn)在有個(gè)需求,需要列出一臺(tái) Linux 機(jī)器上所有的 RPM 包并對(duì)每個(gè)包附上簡(jiǎn)短的描述。我為北卡羅來(lái)納州工作的時(shí)候,曾經(jīng)遇到過(guò)這種需求。由于當(dāng)時(shí)開(kāi)源尚未得到州政府的“批準(zhǔn)”,而且我只在臺(tái)式機(jī)上使用 Linux,對(duì)技術(shù)一竅不通的老板(PHB)需要我列出我計(jì)算機(jī)上安裝的所有軟件,以便他們可以“批準(zhǔn)”一個(gè)特例。
你怎么實(shí)現(xiàn)它?有一種方法是,已知 rpm –qa
命令提供了 RPM 包的完整描述,包括了白癡老板想要的東西:軟件名稱和概要描述。
讓我們一步步執(zhí)行出最后的結(jié)果。首先,列出所有的 RPM 包:
[student@studentvm1 testdir]$ rpm -qaperl-HTTP-Message-6.18-3.fc29.noarchperl-IO-1.39-427.fc29.x86_64perl-Math-Complex-1.59-429.fc29.noarchlua-5.3.5-2.fc29.x86_64java-11-openjdk-headless-11.0.ea.28-2.fc29.x86_64util-linux-2.32.1-1.fc29.x86_64libreport-fedora-2.9.7-1.fc29.x86_64rpcbind-1.2.5-0.fc29.x86_64libsss_sudo-2.0.0-5.fc29.x86_64libfontenc-1.1.3-9.fc29.x86_64<snip>
用 sort
和 uniq
命令對(duì)列表進(jìn)行排序和打印去重后的結(jié)果(有些已安裝的 RPM 包具有相同的名字):
[student@studentvm1 testdir]$ rpm -qa | sort | uniqa2ps-4.14-39.fc29.x86_64aajohan-comfortaa-fonts-3.001-3.fc29.noarchabattis-cantarell-fonts-0.111-1.fc29.noarchabiword-3.0.2-13.fc29.x86_64abrt-2.11.0-1.fc29.x86_64abrt-addon-ccpp-2.11.0-1.fc29.x86_64abrt-addon-coredump-helper-2.11.0-1.fc29.x86_64abrt-addon-kerneloops-2.11.0-1.fc29.x86_64abrt-addon-pstoreoops-2.11.0-1.fc29.x86_64abrt-addon-vmcore-2.11.0-1.fc29.x86_64<snip>
以上命令得到了想要的 RPM 列表,因此你可以把這個(gè)列表作為一個(gè)循環(huán)的輸入信息,循環(huán)最終會(huì)打印每個(gè) RPM 包的詳細(xì)信息:
[student@studentvm1 testdir]$ for RPM in `rpm -qa | sort | uniq` ; do rpm -qi $RPM ; done
這段代碼產(chǎn)出了多余的信息。當(dāng)循環(huán)結(jié)束后,下一步就是提取出白癡老板需要的信息。因此,添加一個(gè) egrep
命令用來(lái)搜索匹配 ^Name
或 ^Summary
的行。脫字符(^
)表示行首,整個(gè)命令表示顯示所有以 Name 或 Summary 開(kāi)頭的行。
[student@studentvm1 testdir]$ for RPM in `rpm -qa | sort | uniq` ; do rpm -qi $RPM ; done | egrep -i "^Name|^Summary"Name : a2psSummary : Converts text and other types of files to PostScriptName : aajohan-comfortaa-fontsSummary : Modern style true type fontName : abattis-cantarell-fontsSummary : Humanist sans serif fontName : abiwordSummary : Word processing programName : abrtSummary : Automatic bug detection and reporting tool<snip>
在上面的命令中你可以試試用 grep
代替 egrep
,你會(huì)發(fā)現(xiàn)用 grep
不能得到正確的結(jié)果。你也可以通過(guò)管道把命令結(jié)果用 less
過(guò)濾器來(lái)查看。最終命令像這樣:
[student@studentvm1 testdir]$ for RPM in `rpm -qa | sort | uniq` ; do rpm -qi $RPM ; done | egrep -i "^Name|^Summary" > RPM-summary.txt
這個(gè)命令行程序用到了管道、重定向和 for
循環(huán),這些全都在一行中。它把你的 CLI 程序的結(jié)果重定向到了一個(gè)文件,這個(gè)文件可以在郵件中使用或在其他地方作為輸入使用。
這個(gè)一次一步構(gòu)建程序的過(guò)程讓你能看到每步的結(jié)果,以此來(lái)確保整個(gè)程序以你期望的流程進(jìn)行且輸出你想要的結(jié)果。
白癡老板最終收到了超過(guò) 1900 個(gè)不同的 RPM 包的清單,我嚴(yán)重懷疑根本就沒(méi)人讀過(guò)這個(gè)列表。我給了他們想要的東西,沒(méi)有從他們嘴里聽(tīng)到過(guò)任何關(guān)于 RPM 包的信息。
Bash 中還有兩種其他類(lèi)型的循環(huán)結(jié)構(gòu):while
和 until
結(jié)構(gòu),兩者在語(yǔ)法和功能上都類(lèi)似。這些循環(huán)結(jié)構(gòu)的基礎(chǔ)語(yǔ)法很簡(jiǎn)單:
while [ expression ] ; do list ; done
邏輯解釋?zhuān)罕磉_(dá)式(expression
)結(jié)果為 true 時(shí),執(zhí)行程序語(yǔ)句 list
。表達(dá)式結(jié)果為 false 時(shí),退出循環(huán)。
until [ expression ] ; do list ; done
邏輯解釋?zhuān)簣?zhí)行程序語(yǔ)句 list
,直到表達(dá)式的結(jié)果為 true。當(dāng)表達(dá)式結(jié)果為 true 時(shí),退出循環(huán)。
while
循環(huán)用于當(dāng)邏輯表達(dá)式結(jié)果為 true 時(shí)執(zhí)行一系列程序語(yǔ)句。假設(shè)你的 PWD 仍是 ~/testdir
。
最簡(jiǎn)單的 while
循環(huán)形式是這個(gè)會(huì)一直運(yùn)行下去的循環(huán)。下面格式的條件語(yǔ)句永遠(yuǎn)以 true
作為返回。你也可以用簡(jiǎn)單的 1
代替 true
,結(jié)果一樣,但是這解釋了 true 表達(dá)式的用法。
[student@studentvm1 testdir]$ X=0 ; while [ true ] ; do echo $X ; X=$((X+1)) ; done | head0123456789[student@studentvm1 testdir]$
既然你已經(jīng)學(xué)了 CLI 的各部分知識(shí),那就讓它變得更有用處。首先,為了防止變量 $X
在前面的程序或 CLI 命令執(zhí)行后有遺留的值,設(shè)置 $X
的值為 0。然后,因?yàn)檫壿嫳磉_(dá)式 [ true ]
的結(jié)果永遠(yuǎn)是 1,即 true,在 do
和 done
中間的程序指令列表會(huì)一直執(zhí)行 — 或者直到你按下 Ctrl+C
抑或發(fā)送一個(gè) 2 號(hào)信號(hào)給程序。那些程序指令是算數(shù)擴(kuò)展,用來(lái)打印變量 $X
當(dāng)前的值并加 1.
《系統(tǒng)管理員的 Linux 哲學(xué)》的信條之一是追求優(yōu)雅,實(shí)現(xiàn)優(yōu)雅的一種方式就是簡(jiǎn)化。你可以用操作符 ++
來(lái)簡(jiǎn)化這個(gè)程序。在第一個(gè)例子中,變量當(dāng)前的值被打印出來(lái),然后變量的值增加了。可以在變量后加一個(gè) ++
來(lái)表示這個(gè)邏輯:
[student@studentvm1 ~]$ X=0 ; while [ true ] ; do echo $((X++)) ; done | head0123456789
現(xiàn)在刪掉程序最后的 | head
再運(yùn)行一次。
在下面這個(gè)版本中,變量在值被打印之前就自增了。這是通過(guò)在變量之前添加 ++
操作符實(shí)現(xiàn)的。你能看出區(qū)別嗎?
[student@studentvm1 ~]$ X=0 ; while [ true ] ; do echo $((++X)) ; done | head123456789
你已經(jīng)把打印變量的值和自增簡(jiǎn)化到了一條語(yǔ)句。類(lèi)似 ++
操作符,也有 --
操作符。
你需要一個(gè)在循環(huán)到某個(gè)特定數(shù)字時(shí)終止循環(huán)的方法。把 true 表達(dá)式換成一個(gè)數(shù)字比較表達(dá)式來(lái)實(shí)現(xiàn)它。這里有一個(gè)循環(huán)到 5 終止的程序。在下面的示例代碼中,你可以看到 -le
是 “小于或等于” 的數(shù)字邏輯操作符。整個(gè)語(yǔ)句的意思:只要 $X
的值小于或等于 5,循環(huán)就一直運(yùn)行。當(dāng) $X
增加到 6 時(shí),循環(huán)終止。
[student@studentvm1 ~]$ X=0 ; while [ $X -le 5 ] ; do echo $((X++)) ; done012345[student@studentvm1 ~]$
until
命令非常像 while
命令。不同之處是,它直到邏輯表達(dá)式的值是 true
之前,會(huì)一直循環(huán)??匆幌逻@種結(jié)構(gòu)最簡(jiǎn)單的格式:
[student@studentvm1 ~]$ X=0 ; until false ; do echo $((X++)) ; done | head0123456789[student@studentvm1 ~]$
它用一個(gè)邏輯比較表達(dá)式來(lái)計(jì)數(shù)到一個(gè)特定的值:
[student@studentvm1 ~]$ X=0 ; until [ $X -eq 5 ] ; do echo $((X++)) ; done01234[student@studentvm1 ~]$ X=0 ; until [ $X -eq 5 ] ; do echo $((++X)) ; done12345[student@studentvm1 ~]$
以上是“怎么用Bash編程實(shí)現(xiàn)循環(huán)”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)站題目:怎么用Bash編程實(shí)現(xiàn)循環(huán)
網(wǎng)頁(yè)網(wǎng)址:http://www.rwnh.cn/article42/phodec.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、、用戶體驗(yàn)、建站公司、關(guān)鍵詞優(yōu)化、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)