trap ERR 的用法

why

經常再寫 script 的時候需要一些方式做 error exit。而 bash 剛好預設有 set -e 可以用。

問題是,每次 set -e 作用的時候 你並不知道哪裡 error exit,除非再配合 -x 參數;而 -x 常常有太多訊息,不划算!

所以,我需要知道的是,當我的 script 遇到錯誤的時候可以丟 message。man bash 裏面有一段描述是:

-e Exit immediately if a pipeline (which may consist of a single simple command), a list, or a compound command (see SHELL GRAMMAR above), exits with a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command's return value is being inverted with !. If a compound command other than a subshell returns a non-zero status because a command failed while -e was being ignored, the shell does not exit. A trap on ERR, if set, is executed before the shell exits. This option applies to the shell environment and each subshell environment separately (see COMMAND EXECUTION ENVIRONMENT above), and may cause subshells to exit before executing all the commands in the subshell.

所以,還是搞不清楚 trap on ERR 是什麼意思,不過這應該是關鍵,所以網路找到幾篇不錯的文章:

  1. http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html
  2. http://unix.stackexchange.com/questions/125607/proper-usage-of-exit-err-traps-in-bash-scripts
  3. http://unix.stackexchange.com/questions/39623/trap-err-and-echoing-the-error-line

大致上就是用 trap 可以做到,格式是:trap "commands" signals 當shell接收到signals指定的信號時,執行commands命令。 所以可以用來時做成當街收到 ERR 時可以跑些像是echo的指令,例如

1
2
3
4
5
6
7
#!/bin/bash
set -e
trap "echo error exit for grep" ERR
ls /ho
echo "right or error ?"
die "test"
echo "right or error 2 ?"

執行起來

./test.sh
ls: 無法存取 /ho: 沒有此一檔案或目錄
error exit for grep

這是最陽春的用法了吧!但是已經能夠再多做發揮了!

Comments