如何在程式化腳本 (shell script) 內忽略異常錯誤結束 (exit(1))

快快樂樂學 shell scripts
最近在試著改善及整合公司其中一個專案的多國語系 (I18N) 自動化流程 (沒錯,又是熟悉的 I18N 好朋友)。除了根據現有的開發流程進行客製化的設計外,一路從開發、驗證、上線,每一個環節都需要考慮到流暢度與困難點,所幸有一些先前的小經驗,不過最後還是整整花了相當充實的三天半左右才完工。

在撰寫自動化流程腳本時遇到了一個有趣的小問題,解完後我覺得這問題雖然小卻也挺有意思的。於是我隔天就提出來跟公司的同事們一起討論,在產生了一些腦力激盪的小火花後,決定花點時間把問題和解法寫出來,一方面替很久沒寫的網誌灌灌水,另一方面則是希望拋出了這塊小磚後,會有一些不一樣,甚至更好、更有趣的大玉會冒出來一起討論。

問題

有一個 shell script 裡面執行了三個指令:
  1. git add .
  2. git commit -m "blahblahblah"
  3. git push
唯一的條件是:這個 shell script 不允許有任何的異常錯誤發生,因為有異常錯誤發生會中斷這個 shell script,也就是在運行指令時都必須要是 exit(0) 才可以。所以也可以想成 shell script 是長這樣:
function run_cmd(){
git add .
git commit -m "blahblahblah"
git push
}
run_cmd()
ret=$?
if [ $ret -gt 0 ]; then
    echo "Error!"
fi 

所以問題點在哪?

假設這個 script 在執行過 1. git add . 後,repo 裡並沒有任何檔案有被更改,正常來說,在執行 2. git commit -m "blahblahblah" 時 git 就會丟出類似下面這樣的訊息:
On branch master
Your branch is up-to-date with 'migme/master'.
nothing to commit, working directory clean
因為 git 發現沒有檔案可以 commit 後拋出了 exit(1) 異常結束 (可以用 echo $? 查看得知),最後進而導致 script 接到錯誤產生也異常結束。

於是,要怎樣忽略掉 git 所拋出的異常錯誤,讓後續的指令能夠順利執行呢?

最後大概有兩種比較短的解法:
  1. 用 pipe:
    git commit -m "blahblah" | cat
  2. 用 true:
    git commit -m "blahblah" || true

這兩種都可以忽略掉 exit(1) 產生時的異常錯誤,不過這兩種方法所表示的意義有些不同,就讓客倌您自己細細品嚐跟探討了。