Bash 中的 try/catch

前幾天在做某個測試性專案,過程中調整 mongodb 的 automation build script 時遇到個狀況:module 會在 init 時執行 create role 跟 user,但有些 role 與 user 會被重複建立而出錯,正統的做法當然是先檢查資料是否存在,不存在才執行建立,但是這樣的動作就直接影響到原始專案的內容與流程,跟測試性專案的出發點不符,所以想要簡單的避開 bash 的 error,直接忽略 error 繼續執行

簡單 google 後,發現寫法簡單,但為了加深印象這是簡單紀錄一下用法

基本環境說明

  1. macOS Monterey 12.0.1
  2. bash 3.2.57(1)-release-(x86_64-apple-darwin21)

使用方式

  • 使用 ||command1 || command2

    當 command1 出錯就會接著執行 command2

    • 範例1:嘗試 cat 不存在的 none.log,最後會印出 always success

      cat none.log && echo "try success" || echo "always success"
      

      1fail

    • 範例1:cat 存在的 test.log,會印出 try success

      cat test.log && echo "try success" || echo "always success"
      

      2pass

    • command 是多行的情況

      • 語法

        {
            cat test.log &&
            echo "fail"
        } || {
            echo "success"
        }
        
  • 使用 set +e

    忽略 command error

    set +e
    cat none.log
    echo "success"
    set -e
    

    3sete

  • 使用 trap

    • 語法

      遇到 信號執行語法

      trap {執行語法} {信號}
      
    • 範例

      trap "echo success" EXIT
      cat none.log
      exit 64
      

    4trap

心得

bash 沒有 try/catch 的 function,但透過上述的幾種方式還是能達到目的

有人提到不該使用 set +e 因為這個設定全域的,可能造成 server 上其他正在執行的 bash 錯誤被吞掉

至於哪個方式比較好,我還在探索中,暫時還沒辦法給出結論

參考資訊

  1. Is there a TRY CATCH command in Bash
  2. 利用 trap 執行所有 Bash 退出前該做的事情
  3. Bash 脚本 set 命令教程