<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                在前面的章節中,我們開發了菜單驅動程序,來產生各種各樣的系統信息。雖然程序能夠運行, 但它仍然存在重大的可用問題。它只能執行單一的選擇,然后終止。更糟糕地是,如果做了一個 無效的選擇,程序會以錯誤終止,而沒有給用戶提供再試一次的機會。如果我們能構建程序, 以致于程序能夠重復顯示菜單,而且能一次由一次的選擇,直到用戶選擇退出程序,這樣的程序會更好一些。 在這一章中,我們將看一個叫做循環的程序概念,其可用來使程序的某些部分重復。shell 為循環提供了三個復合命令。 本章我們將查看其中的兩個命令,隨后章節介紹第三個命令。 ## 循環 日常生活中充滿了重復性的活動。每天去散步,遛狗,切胡蘿卜,所有任務都要重復一系列的步驟。 讓我們以切胡蘿卜為例。如果我們用偽碼表達這種活動,它可能看起來像這樣: 1. 準備切菜板 2. 準備菜刀 3. 把胡蘿卜放到切菜板上 4. 提起菜刀 5. 向前推進胡蘿卜 6. 切胡蘿卜 7. 如果切完整個胡蘿卜,就退出,要不然回到第四步繼續執行 從第四步到第七步形成一個循環。重復執行循環內的動作直到滿足條件“切完整個胡蘿卜”。 ### while bash 能夠表達相似的想法。比方說我們想要按照順序從1到5顯示五個數字。可如下構造一個 bash 腳本: ~~~ #!/bin/bash # while-count: display a series of numbers count=1 while [ $count -le 5 ]; do echo $count count=$((count + 1)) done echo "Finished." ~~~ 當執行的時候,這個腳本顯示如下信息: ~~~ [me@linuxbox ~]$ while-count 1 2 3 4 5 Finished. ~~~ while 命令的語法是: ~~~ while commands; do commands; done ~~~ 和 if 一樣, while 計算一系列命令的退出狀態。只要退出狀態為零,它就執行循環內的命令。 在上面的腳本中,創建了變量 count ,并初始化為1。 while 命令將會計算 test 命令的退出狀態。 只要 test 命令返回退出狀態零,循環內的所有命令就會執行。每次循環結束之后,會重復執行 test 命令。 第六次循環之后, count 的數值增加到6, test 命令不再返回退出狀態零,且循環終止。 程序繼續執行循環之后的語句。 我們可以使用一個 while 循環,來提高前面章節的 read-menu 程序: ~~~ #!/bin/bash # while-menu: a menu driven system information program DELAY=3 # Number of seconds to display results while [[ $REPLY != 0 ]]; do clear cat <<- _EOF_ Please Select: 1\. Display System Information 2\. Display Disk Space 3\. Display Home Space Utilization 0\. Quit _EOF_ read -p "Enter selection [0-3] > " if [[ $REPLY =~ ^[0-3]$ ]]; then if [[ $REPLY == 1 ]]; then echo "Hostname: $HOSTNAME" uptime sleep $DELAY fi if [[ $REPLY == 2 ]]; then df -h sleep $DELAY fi if [[ $REPLY == 3 ]]; then if [[ $(id -u) -eq 0 ]]; then echo "Home Space Utilization (All Users)" du -sh /home/* else echo "Home Space Utilization ($USER)" du -sh $HOME fi sleep $DELAY fi else echo "Invalid entry." sleep $DELAY fi done echo "Program terminated." ~~~ 通過把菜單包含在 while 循環中,每次用戶選擇之后,我們能夠讓程序重復顯示菜單。只要 REPLY 不 等于”0”,循環就會繼續,菜單就能顯示,從而用戶有機會重新選擇。每次動作完成之后,會執行一個 sleep 命令,所以在清空屏幕和重新顯示菜單之前,程序將會停頓幾秒鐘,為的是能夠看到選項輸出結果。 一旦 REPLY 等于“0”,則表示選擇了“退出”選項,循環就會終止,程序繼續執行 done 語句之后的代碼。 ## 跳出循環 bash 提供了兩個內部命令,它們可以用來在循環內部控制程序流程。這個 break 命令立即終止一個循環, 且程序繼續執行循環之后的語句。這個 continue 命令導致程序跳過循環中剩余的語句,且程序繼續執行 下一次循環。這里我們看看采用了 break 和 continue 兩個命令的 while-menu 程序版本: ~~~ #!/bin/bash # while-menu2: a menu driven system information program DELAY=3 # Number of seconds to display results while true; do clear cat <<- _EOF_ Please Select: 1\. Display System Information 2\. Display Disk Space 3\. Display Home Space Utilization 0\. Quit _EOF_ read -p "Enter selection [0-3] > " if [[ $REPLY =~ ^[0-3]$ ]]; then if [[ $REPLY == 1 ]]; then echo "Hostname: $HOSTNAME" uptime sleep $DELAY continue fi if [[ $REPLY == 2 ]]; then df -h sleep $DELAY continue fi if [[ $REPLY == 3 ]]; then if [[ $(id -u) -eq 0 ]]; then echo "Home Space Utilization (All Users)" du -sh /home/* else echo "Home Space Utilization ($USER)" du -sh $HOME fi sleep $DELAY continue fi if [[ $REPLY == 0 ]]; then break fi else echo "Invalid entry." sleep $DELAY fi done echo "Program terminated." ~~~ 在這個腳本版本中,我們設置了一個無限循環(就是自己永遠不會終止的循環),通過使用 true 命令 為 while 提供一個退出狀態。因為 true 的退出狀態總是為零,所以循環永遠不會終止。這是一個 令人驚訝的通用腳本編程技巧。因為循環自己永遠不會結束,所以由程序員在恰當的時候提供某種方法來跳出循環。 此腳本,當選擇”0”選項的時候,break 命令被用來退出循環。continue 命令被包含在其它選擇動作的末尾, 為的是更加高效執行。通過使用 continue 命令,當一個選項確定后,程序會跳過不需要的代碼。例如, 如果選擇了選項”1”,則沒有理由去測試其它選項。 ### until 這個 until 命令與 while 非常相似,除了當遇到一個非零退出狀態的時候, while 退出循環, 而 until 不退出。一個 until 循環會繼續執行直到它接受了一個退出狀態零。在我們的 while-count 腳本中, 我們繼續執行循環直到 count 變量的數值小于或等于5。我們可以得到相同的結果,通過在腳本中使用 until 命令: ~~~ #!/bin/bash # until-count: display a series of numbers count=1 until [ $count -gt 5 ]; do echo $count count=$((count + 1)) done echo "Finished." ~~~ 通過把 test 表達式更改為 $count -gt 5 , until 會在正確的時間終止循環。決定使用 while 循環 還是 until 循環,通常是選擇一個 test 可以編寫地很清楚的循環。 ## 使用循環讀取文件 while 和 until 能夠處理標準輸入。這就可以使用 while 和 until 處理文件。在下面的例子中, 我們將顯示在前面章節中使用的 distros.txt 文件的內容: ~~~ #!/bin/bash # while-read: read lines from a file while read distro version release; do printf "Distro: %s\tVersion: %s\tReleased: %s\n" \ $distro \ $version \ $release done < distros.txt ~~~ 為了重定向文件到循環中,我們把重定向操作符放置到 done 語句之后。循環將使用 read 從重定向文件中讀取 字段。這個 read 命令讀取每個文本行之后,將會退出,其退出狀態為零,直到到達文件末尾。到時候,它的 退出狀態為非零數值,因此終止循環。也有可能把標準輸入管道到循環中。 ~~~ #!/bin/bash # while-read2: read lines from a file sort -k 1,1 -k 2n distros.txt | while read distro version release; do printf "Distro: %s\tVersion: %s\tReleased: %s\n" \ $distro \ $version \ $release done ~~~ 這里我們接受 sort 命令的標準輸出,然后顯示文本流。然而,因為管道將會在子 shell 中執行 循環,當循環終止的時候,循環中創建的任意變量或賦值的變量都會消失,記住這一點很重要。 ## 總結 通過引入循環,和我們之前遇到的分支,子例程和序列,我們已經介紹了程序流程控制的主要類型。 bash 還有一些錦囊妙計,但它們都是關于這些基本概念的完善。 ## 拓展閱讀 * Linux 文檔工程中的 Bash 初學者指南一書中介紹了更多的 while 循環實例: [http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html](http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html) * Wikipedia 中有一篇關于循環的文章,其是一篇比較長的關于流程控制的文章中的一部分: [http://en.wikipedia.org/wiki/Control_flow#Loops](http://en.wikipedia.org/wiki/Control_flow#Loops)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看