如何 debug ShellScript?
看到 CIH 介紹了一個 debug Shell Script 技巧,在大量 debug 時候,不需要再拼命塞一堆echo在程式碼。
方法很簡單,只需要輸入
$ (exec 111> log ;
export SHELLOPTS BASH_XTRACEFD=111 PS4='($BASH_SOURCE:$LINENO:$FUNCNAME): ' ;
set -x ; ./cih.sh)
作用是
exec 111> log
:這條命令打開一個名為log
的文件用於寫入,並將它關聯到file descriptor 111 上。這意味著接下來的輸出可以被重定向到這個文件。export SHELLOPTS
:這條命令將當前 shell 的選項導出為環境變量,使得子 shell 也能繼承這些選項。BASH_XTRACEFD=111
:這是一個環境變量,用於指定當set -x
啟用時,所有的 trace 輸出應該被寫入哪個 descriptor。在這裡,它被設定為 111,即之前打開的log
文件。PS4='($BASH_SOURCE:$LINENO:$FUNCNAME): '
:這條命令設置了當set -x
啟用時,每條命令前面的提示信息格式。$BASH_SOURCE
顯示當前執行腳本的名稱,$LINENO
顯示當前行號,$FUNCNAME
顯示當前函數名。這樣可以讓日誌中的每條命令都帶有易於定位的訊息。set -x
:啟用 shell 的追蹤模式,會將執行的每條命令及其參數打印到 stderr 。在本例中,由於設置了BASH_XTRACEFD
,輸出會被重定向到 file descriptor 111,也就是log
文件。./cih.sh
:最後執行名為cih.sh
的腳本文件。
假設 cih.sh
的內容是產生一個亂數。
#!/bin/bash
function my_func()
{
var=$RANDOM
}
my_func
那麼執行後的效果如下
$ (exec 111> log ; export SHELLOPTS BASH_XTRACEFD=111 PS4='($BASH_SOURCE:$LINENO:$FUNCNAME): ' ; set -x ; ./cih.sh)
$ cat log
(:1:): ./cih.sh
(./cih.sh:8:): my_func
(./cih.sh:5:my_func): var=21742
老司機的技巧果然不同凡響。