初學Bash時, 我從未想過去debug Bash腳本, 也從未想過Bash腳本也能debug. 隨著技術的增長, 寫的腳本越來越複雜, 使用echo列印日誌來調試腳本的方式越來越捉襟見肘了. 直到某天 通讀了一遍Bash Reference Manual, 才發現Bash腳本也是可以debug的. ...
初學Bash時, 我從未想過去debug Bash腳本, 也從未想過Bash腳本也能debug. 隨著技術的增長, 寫的腳本越來越複雜, 使用echo列印日誌來調試腳本的方式越來越捉襟見肘了. 直到某天
通讀了一遍Bash Reference Manual, 才發現Bash腳本也是可以debug的. 下麵就介紹三種debug Bash腳本的方式.
1. debug某個腳本
執行腳本有兩種方式, 一是bash script.sh
的方式, 二是./script.sh
的方式. 通過第一種方式執行腳本時, 加上-x
選項即可debug腳本.
輸出的結果中, 以+
開頭的行就是debug輸出的信息.
$ cat test.sh
#!/bin/bash
echo "Time: $(date)"
echo "User: $USER"
echo "Home: $HOME"
$ bash -x test.sh
++date
+echo 'Time: Mon 11 Jul 2022 11:29:37 PM CST'
Time: Mon 11 Jul 2022 11:29:37 PM CST
+echo 'User: wbourne '
User: wbourne
+echo 'Home: /home/wbourne '
Home: /home/wbourne
2. debug特定腳本
前面說過執行腳本有兩種方式, 那如果是用第二種方式執行腳本如何debug呢? 修改腳本的shabang為bash -x
即可. 每次執行腳本就會輸出debug信息.
此方式適合debug某個特定的腳本, 執行腳本時會預設輸出debug信息; 而上面的第一種方式則適合debug任何腳本.
$ cat test.sh
#!/bin/bash -x
echo "Time: $(date)"
echo "User: $USER"
echo "Home: $HOME"
$ ./test.sh
++date
+echo 'Time: Mon 11 Jul 2022 11:32:52 PM CST'
Time: Mon 11 Jul 2022 11:32:52 PM CST
+echo 'User: wbourne '
User: wbourne
+echo 'Home: /home/wbourne '
Home: /home/wbourne
請註意: 如果修改腳本的shabang為bash -x
, 又以bash script.sh
的方式執行腳本, 會發生什麼? 居然沒有輸出debug信息!!!
設置shabang表示設置一個預設解釋器, 如果沒有指定解釋器才會使用shabang中寫的解釋器. 以bash script.sh
的方式執行腳本則指定瞭解釋器為bash, 所以不會有debug信息.
$ bash test.sh
Time: Mon 11 Jul 2022 11:32:12 PM CST
User: wbourne
Home: /home/wbourne
3. debug腳本某一部分
如果腳本比較長, 我們之關心其中一部分, 就可以使用Bash內置命令set
來debug部分腳本.
set -x
表示開啟debug, set +x
表示關閉debug
$ cat test.sh
#!/bin/bash
echo "Time: $(date)"
set -x
echo "User: $USER"
set +x
echo "Home: $HOME"
$ ./test.sh
Time: Mon 11 Jul 2022 11:33:43 PM CST
+echo 'User: wbourne '
User: wbourne
+set +x
Home: /home/wbourne
4. PS4
既然是debug, 那肯定要詳細才好. 上述debug只不過是輸出了變數值而已, 是不是可以顯示更多信息? 當然是可以的, debug信息的提示符是環境變數PS4, 預設為+
, 我們可以更改PS4的值, 使其輸出腳本名, 函數名, 行數等更詳細的信息. 這個提示符還是綠色的哦!
$ echo $PS4
+
$ export PS4='+\e[01;32m[${BASH_SOURCE}:${FUNCNAME[0]}:${LINENO}]\e[00m'
$ bash -x test.sh
++[test.sh::3]date
+[test.sh::3]echo 'Time: Mon 11 Jul 2022 11:35:08 PM CST'
Time: Mon 11 Jul 2022 11:35:08 PM CST
+[test.sh::4]echo 'User: wbourne '
User: wbourne
+[test.sh::5]echo 'Home: /home/wbourne '
Home: /home/wbourne