shell編程其實真的很簡單(四)

来源:http://www.cnblogs.com/dongying/archive/2017/02/08/6376166.html
-Advertisement-
Play Games

上篇我們學習了shell中條件選擇語句的用法。接下來本篇就來學習迴圈語句。在shell中,迴圈是通過for, while, until命令來實現的。下麵就分別來看看吧。 for for迴圈有兩種形式: for in語句 基本格式如下: for var in list do commands done ...


上篇我們學習了shell中條件選擇語句的用法。接下來本篇就來學習迴圈語句。在shell中,迴圈是通過for, while, until命令來實現的。下麵就分別來看看吧。

for

for迴圈有兩種形式:

for-in語句

基本格式如下:

for var in list 
do
    commands
done

list代表要迴圈的值,在每次迴圈的時候,會把當前的值賦值給var(變數名而已,隨意定), 這樣在迴圈體中就可以直接通過$var獲取當前值了。

先來一個例子吧:

#!/bin/bash
for str in a b c d e
do
    echo $str
done    

以上會根據空格將abcde分割,然後依次輸出出來。

如果以上例子不是以空格分割,而是以逗號(,)分割呢?

#!/bin/bash
list="a,b,c,d,e"
for str in $list
do 
    echo $str
done

結果輸出a,b,c,d,e

造成這個結果的原因是:for...in迴圈預設是迴圈一組通過空格或製表符(tab鍵)或換行符(Enter鍵)分割的值。這個其實是由內部欄位分隔符配置的,它是由系統環境變數IFS定義的。當然,既然是由環境變數定義的,那當然也就能修改啊。

修改IFS值

#!/bin/bash
#定義一個變數oldIFS保存未修改前的IFS的值
oldIFS=$IFS
#修改IFS值,以逗號為分隔符
IFS=$','
list=a,b,c,d,e
list2="a b c d e"
for var in $list
do
    echo $var
done
for var2 in $list2
do
    echo $var2
done
#還原IFS的值
IFS=$oldIFS

以上第一個迴圈會分別輸出abcde幾個值。而第二個迴圈會輸出a b c d e(即未處理)。因為我們把IFS的值設置為逗號了, 當然,不一定要是逗號,想設置什麼,你說了算!

C語言風格的for迴圈

bash中c語言風格的for迴圈遵循如下格式:

for (( variable assignment ; condition ; iteration process ))

一個例子足以說明:

#!/bin/bash
for (( i = 0; i <= 10; i++ ))
do
    echo $i
done    

上面例子迴圈11次,從0到10依次輸出。稍微有過編程基礎的都對此應該很熟悉。就不做詳細闡述了。

while迴圈

如果你習慣了其它語言的while迴圈,那麼到這兒你又會發現這個while迴圈有點變態了。與其它編程語言while的不同在於:在bash中的while語句,看起來似乎是結合了if-then語句(參考上一篇)和for迴圈語句。其基本格式如下:

while test command 
do
    other commands
done

與if-then語句一樣,後面接test命令,如果test後面的命令的退出狀態碼為0. 那麼就進入迴圈,執行do後面的邏輯。要註意在do後面的邏輯中寫條件,避免死迴圈。

既然是接test命令,那麼一切都可以參考if-then的test

示例一:

#!/bin/bash
flag=0
while test $flag -le 10
do
    echo $flag
    # 如果沒有這句,那麼flag的值一直為0,就會無限迴圈執行
    flag=$[$flag + 1]
done

以上判斷flag是否大於或者等於10, 如果滿足條件,那麼輸出當前flag的值,然後再將flag的值加1。最終輸出的結果為0到10的結果。

結合上一篇文章test的寫法,我們還可以將以上示例變形為如下:

示例二:

#!/bin/bash
flag=0
while [ $flag -le 10 ]
do
    echo $flag
    flag=$[$flag + 1]
done

示例三:

flag=0
while (( $flag <= 10 ))
do
    echo $flag
    flag=$[$flag + 1]
done

until迴圈語句

until語句基本格式如下:

until test commands
do
    other commands
done

在掌握while迴圈語句之後, until語句就很簡單了。until語句就是與while語句恰好相反, while語句是在test命令退出狀態碼為0的時候執行迴圈, 而until語句是在test命令退出狀態碼不為0的時候執行。

示例:

#!/bin/bash
flag=0
until (( $flag > 10 ))
do
    echo $flag
    flag=$[ $flag + 1 ]
done

以上輸出0到10的值。until後面的條件與上面while例子完全相反。

好啦,到此,我們學完了shell的迴圈語句啦。不過上面我們寫的迴圈語句都是根據條件執行完畢,如果我們在執行的過程中想退出,該怎麼辦?接下來就繼續看看怎麼控制迴圈語句。

控制迴圈

與其它編程語言一樣,shell是通過break和continue命令來控制迴圈的。下麵就分別來看看二者的基本用法:

break

  1. break用於跳出當前迴圈

示例一:

#!/bin/bash
for (( flag=0; flag <= 10; flag++ ))
do
    if (( $flag == 5 ))
    then
        break
    fi
    echo $flag
done

以上當flag的值為5的時候,退出迴圈。輸出結果為0-4的值。

  1. break用於跳出內層迴圈

示例二:

#!/bin/bash
flag=0
while (( $flag < 10 ))
do
    for (( innerFlag=0; innerFlag < 5; innerFlag++ ))
    do
        if (( $innerFlag == 2 ))
        then
            break
        fi
        echo "innerFlag=$innerFlag"
    done
    echo "outerFlag=$flag"
done

以上代碼在執行內部迴圈for的時候,當innerFlag值為2的時候就會跳出到外層的while迴圈, 由於外層迴圈一直flag都為0, 所以while會成為一個死迴圈,不停的輸出:

...

innerFlag=0

innerFlag=1

outerFlag=0

...

  1. break用於跳出外層迴圈

break 可後接數字,用於表示退出當前迴圈的外層的第幾層迴圈。

示例三:

#!/bin/bash
flag=0
while (( $flag < 10 ))
do
    for (( innerFlag=0; innerFlag < 5; innerFlag++ ))
    do
        if (( $innerFlag == 2 ))
        then
              # 2表示外面一層迴圈
            break 2
        fi
        echo "innerFlag=$innerFlag"
    done
    echo "outerFlag=$flag"
done

與上面例子相比,本例就只是在break後面跟了個數字2,表示退出外面的第一層迴圈。最終輸出:

innerFlag=0

innerFlag=1

continue

continue表示終止當前的一次迴圈,進入下一次迴圈,註意,continue後面的語句不會執行。

continue的語法與break一樣,因此,就只做一個示例演示啦。

示例:

flag=0
while (( $flag <= 10 ))
do
    if (( $flag == 5 ))
    then
        flag=$[$flag+1]
        continue
    fi
    echo "outerFlag=$flag"
    for (( innerFlag=11; innerFlag < 20; innerFlag++ ))
    do
        if (( $innerFlag == 16 ))
        then
            flag=$[$flag+1]
            continue 2
        fi
        echo "innerFlag=$innerFlag"
    done
done

以上例子: 當for迴圈中innerFlag的值為16的時候會跳到外層while迴圈,當外層迴圈的flag的值為5的時候,會直接跳過本次迴圈,然後進入下一次迴圈,因此在輸出的結果中,不會出現outerFlag=5的情況。

我的博客www.javafan.cn



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一般察看函數運行時堆棧的方法是使用GDB(bt命令)之類的外部調試器,但是,有些時候為了分析程式的BUG,(主要針對長時間運行程式的分析),在程式出錯時列印出函數的調用堆棧是非常有用的。 在glibc頭文件"execinfo.h"中聲明瞭三個函數用於獲取當前線程的函數調用堆棧。 int backtr ...
  • Linux小知識分享(一) 標簽(空格分隔): 陳思齊 1,多進程與多線程 1.1 什麼是進程? 程式並不能單獨運行,只有將程式裝載到記憶體中,系統為它分配資源才能運行,而這種承載程式運行的資源池(指令集合)就稱之為進程。 1.2什麼是多進程? 在多道編程中,我們允許多個程式同時載入到記憶體中,在操作系 ...
  • 第十二節 linux三劍客之sed命令精講 標簽(空格分隔): Linux實戰教學筆記 陳思齊 [更多資料點我查看][1] 1,前言 我們都知道,在Linux中一切皆文件,比如配置文件,日誌文件,啟動文件等等。如果我們相對這些文件進行一些編輯查詢等操作時,我們可能會想到一些vi,vim,cat,mo ...
  • 僅供參考…… 測試使用環境:Tplink & Tenda渣渣路由器。其他環境或不同。 設置註意事項:副路由器網段設置和主路由一致。主路由不需要開啟WDS、副路由器開啟WDS(連接ok,狀態即顯示"成功")、主副路由通道需要保持一致(手動設置)、DHCP服務開啟(設置網關) IP地址池設置不妥時,一臺 ...
  • 打開終端,輸入su root,進入root賬戶 在/boot/grub2/下麵有個grub.cfg文件 在命令行輸入vim /boot/grub2/grub.cfg 在### BEGIN /etc/grub.d/10_linux ### 後面加上一段 menuentry 'Windows7'{ in ...
  • Linux系統信息存放在文件里,文件與普通的公務文件類似。每個文件都有自己的名字、內容、存放地址及其它一些管理信息,如文件的用戶、文件的大小等。文件可以是一封信、一個通訊錄,或者是程式的源語句、程式的數據,甚至可以包括可執行的程式和其它非正文內容。Linux文件系統具有良好的結構,系統提供了很多文件 ...
  • 用戶訪問示意圖: ...
  • 實例1:每1分鐘執行一次myCommand * * * * * myCommand 實例2:每小時的第3和第15分鐘執行 3,15 * * * * myCommand 實例3:在上午8點到11點的第3和第15分鐘執行 3,15 8-11 * * * myCommand 實例4:每隔兩天的上午8點到1 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...