<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          教你寫出健壯可靠的shell腳本!

          共 2328字,需瀏覽 5分鐘

           ·

          2020-08-17 19:33


          點擊「閱讀原文」查看良許原創(chuàng)精品視頻。

          如果秉承著能跑就行的態(tài)度寫shell腳本,是很自在的,但是如果你想要寫出健壯,可靠的shell腳本,可沒那么容易。那么有什么可操作的經驗或者方法嗎?

          語法檢查

          第一個最簡單的方法就是利用工具對腳本進行檢查,它能最大程度地發(fā)現shell腳本中存在的語法錯誤,如果你還不知道,建議你絕對不要錯過。

          而為了保證腳本健壯可靠,那么就需要保證腳本在一些特殊的情況及早出現,避免漏網之魚。來看看有哪些可行的技巧。

          腳本失敗時即退出

          可以在腳本的開頭設置如下:

          set?-e

          舉個例子:

          #!/bin/bash
          set?-e
          lp????#這里運行會出錯
          date

          這種情況下,運行一旦出錯就會退出,不放過一個問題:

          $?./test.sh
          lp:?Error?-?no?default?destination?available.

          當然了,這也有不好的地方,有時候命令執(zhí)行本來就可能是失敗的,你還是希望它繼續(xù),可以臨時加上|| true:

          #!/bin/bash
          set?-e
          lp??||?true??
          date

          不過個人覺得這樣的設置用處不是特別大,因為很多時候就是需要處理不同的錯誤情況,而這樣只能要么遇到錯誤退出,要么認為正確,導致無法走到異常分支。
          通過set +e設置回來:

          set?-e
          #command
          set?+e
          #other?command

          打印腳本執(zhí)行過程

          調試階段,你可能想知道整個過程是執(zhí)行了哪些命令,每條命令都具體執(zhí)行了什么,可以利用下面的方式執(zhí)行:

          sh?-x?test.sh

          或者,和上面類似,在開頭加上set -x:

          //來源:公眾號【編程珠璣】
          //作者:守望先生
          #!/bin/bash
          set?-x
          if?[?$#?-lt?1?]
          then
          ???echo??"no?para"
          else
          ???echo?"para?1?$1"
          fi

          執(zhí)行時,輸出如下:

          +?[?0?-le?1?]
          +?echo?no?para
          no?para

          前面帶+的內容就是命令實際執(zhí)行的,你可以看到比較條件是什么,變量被展開成了具體內容,走到了哪個分支,非常清楚。

          顯示未定義的變量

          shell中變量沒有定義,仍然是可以使用的,但是它的結果可能不是你所預期的。舉個例子:

          //來源:公眾號【編程珠璣】
          //作者:守望先生
          #!/bin/bash
          if?[?"$var"?=?"abc"?]
          then
          ???echo??"?not?abc"
          else
          ???echo?"?abc?"
          fi

          這里本來想判斷var的內容是否為abc,實際上var并沒有定義,但是在這里使用并沒有報錯,如果我們想早點發(fā)現這類問題,避免在復雜的腳本中問題被掩蓋,那么可以在開頭加上:

          set?-u

          再次運行就會提示:

          test.sh:?5:?test.sh:?num:?parameter?not?set

          再想象一下,你本來想刪除:

          rm?-rf?$dir/*

          然后dir是空的時候,變成了什么?

          是不是有種后背發(fā)涼的感覺?

          管道命令一個失敗時整個失敗

          有時候我們可能會執(zhí)行類似這樣的命令:

          cat?test.sh?|grep?if?|?cut?-d?';'?-f?2

          三條命令一行執(zhí)行,如果我們希望在其中一條失敗,整個命令就失敗,而避免執(zhí)行后面無意義的命令,那么可以在開始設置:

          set?-o?pipefail

          不設置的情況下,cat test.sh即使執(zhí)行失敗了,后面的grep實際上還會繼續(xù)執(zhí)行,可能會導致一些意想不到的情況發(fā)生,如果不想這樣的情況發(fā)生,那么這樣設置是有幫助的。

          對于靜態(tài)變量使用readonly

          通常我們會在腳本開頭定義一些靜態(tài)變量:

          MY_PATH=/usr/bin

          而為了避免MY_PATH被意外修改,可以這樣:

          readonly?MY_PATH=/usr/bin

          這樣的話,一旦后面有命令嘗試修改,就會報錯。

          #!/bin/bash
          readonly?MY_PATH=/usr/bin
          MY_PATH=/usr/local/bin

          運行一下試試:

          $?./test.sh
          test.sh:?3:?test.sh:?MY_PATH:?is?read?only

          看,給你提示了!

          給變量設置可選的初始值

          例如:

          name=${1:-shouwang}
          echo?"${name}"

          這里讓name為$1,即第一個參數,而當它為空時,令name為shouwang。

          多條命令執(zhí)行使用&&

          例如:

          cmd0;cmd1;cmd1

          這里如果cmd0失敗了,后面的命令仍然會執(zhí)行,而如果不希望后面的命令執(zhí)行,可以使用:

          cmd0?&&?cmd1?&&?cmd1

          使用函數

          腳本本身比較短還好,而腳本一旦變長,不使用函數,將使得腳本很難維護,可讀性也很差。

          總結

          實際上最開始介紹的腳本檢查工具就已經非常有效了,基本的錯誤都能檢查出來,而其他的內容,更多的是關注于腳本調試,不放過任何一個可能的錯誤。

          最后,還是優(yōu)先推薦shellcheck工具。

          良許個人微信


          添加良許個人微信即送3套程序員必讀資料


          → 精選技術資料共享

          → 高手如云交流社群





          本公眾號全部博文已整理成一個目錄,請在公眾號里回復「m」獲??!

          推薦閱讀:

          一文講透 “進程、線程、協(xié)程”

          Linux screen命令詳解

          Linux進程之如何查看進程詳情?


          5T技術資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,單片機,樹莓派,等等。在公眾號內回復「1024」,即可免費獲?。?!


          瀏覽 57
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大香蕉思思精品在线 | 黄色综合 | 免费一级小黄片 | 久久黄免费 | 手机欧美在线 |