2017-09-28 63 views
2

我有一個非常大的腳本(函數包含大約4000行代碼)。這裏是它的一部分:記錄一個bash腳本文件

#!/bin/bash 


. ./functions > /dev/null 2>&1 

some_function(){ 

while true 
do 

CHOICE=$(whiptail --menu "\n\n\n\n\n\n\n\n" --title "Tools" --nocancel $window 20 \ 
"1" "Option1" \ 
"2" "Option2" \ 
"3" "Option3" 3>&1 1>&2 2>&3) 


case $CHOICE in 

    1)echo $1 $2 $3;; 
    2)echo $2 $1 $3;;          
    3)echo $3 $2 $1;; 

esac 
done 
} 



while true; do 
arr=() 
for ((n=1; n<=$node_num; n++)) 
     do 
     node+=($n NODE$n) 
done 


OPTION=$(whiptail --menu "\n\n\n\nPlease choose:\n\n\n" --title "tools" $window 20 "${node[@]}" \ 

case $OPTION in 

     1) some_function 1 2 3 ;; 
     2) some_function 2 1 3 ;; 
     3) some_function 3 1 2 ;; 
esac 
done 

我想記錄腳本中執行的命令。

我迄今爲止嘗試是:

  1. #!/bin/bash -x - >這將記錄所有的輸出,同時也將「垃圾郵件」中與像變量值等不需要的信息日誌,但是這似乎是迄今爲止的最佳方式...
  2. 我試過#!/bin/bash -i,通過設置-o歷史來啓用歷史記錄。這樣做的缺點是會記錄一切。例如,當我調用函數文件時,它會記錄每一行,就像它被執行一樣。
  3. 我曾嘗試創建日誌功能:

    logthis(){ 
        ## print the command to the logfile 
        echo "$(date) [email protected]" >> $historyfile 
        ## run the command and redirect it's error output 
        ## to the logfile 
        eval "[email protected]" 2>> $historyfile 
    } 
    

    這似乎是工作的大部分時間。但是,當我這樣做,例如:

    case $OPTION in 
        1) logthis "some_function 1 2 3" ;; 
        2) some_function 2 1 3 ;; 
        3) some_function 3 1 2 ;; 
    esac 
    

它不會工作,我將失去參數1 2 3

你有沒有做一個優雅的記錄系統是bash裏面的任何其他的想法腳本?

+2

可以使用'set -x'和'set + x'在腳本中根據需要啓用和禁用跟蹤;它是您的選項1的更細粒度版本。 – chepner

+1

選項2不需要'-i'選項;歷史記錄在交互式shell中默認啓用,但不需要*交互式shell。 – chepner

+0

是的,我可以啓用和禁用調試模式,但正在尋找更優雅的方式,而不是通過所有的代碼和設置設置-x/set + x –

回答

4

擺脫日誌功能中的eval。只需編寫"[email protected]"即可執行傳遞的命令。

logthis() { 
    echo "$(date): [email protected]" >> "$historyfile" 
    "[email protected]" 2>> "$historyfile" 
} 

然後,你可以通過簡單地在前面加上logthis日誌的命令。不需要額外的報價。

logthis some_function 1 2 3 

這將很好地保留所有的參數 - 即使它們有空白或其他特殊字符。

我建議對echo命令做一個小改進。如果你使用printf %q它會更好地記錄帶有空格的參數。

echo "$(date):$(printf ' %q' "[email protected]")" >> "$historyfile" 
+0

最後一點,爲什麼不只是使用printf的整個事情? –

+0

'printf'將爲每個額外參數重複格式化字符串。不能這樣做,並在一個'printf'中打印日期。 –

+0

不幸的是,當我嘗試傳遞變量例如:logthis命令$ 1 $ 2東西打破和whiptail窗口不顯示...:/ –

1

嘗試set -v

這並不像解析的set -x命令,就輸出什麼被執行。

set -v 
: all the things 'in' $0, 'yay!' 

輸出準確: all the things 'in' $0, 'yay!'
甚至不解析$ 0

記錄的參數,最小的垃圾郵件。 ;)

考慮圍繞代碼的主要代碼卷繞來管理輸出日誌記錄。

{ # after setup to parse args, set vars & traps, declare funcs, etc 
    your bulk code here 
} 2>&1 | tee /some/file.log 

您可以保存set -x垃圾郵件的--verbose模式。;)

+0

謝謝,但這仍然會記錄所有的whiptail菜單例如。我不能像變量聲明一樣將它們輸出到/ dev/null。 –

+1

您可以將菜單抽象爲在開始時和結束時關閉-v的功能嗎?您要求進行細粒度日誌記錄,因此我擔心您將不得不編寫粒度代碼。 –