2017-08-03 73 views
2

在調試bash shell腳本時,我看到我在代碼的某個部分中犯的錯誤。這個錯誤可以是變量名稱,變量值或一般的代碼行。如何在調試過程中交互地修改shell腳本?

運行調試模式時可以更正它嗎?或者唯一的選擇是退出調試模式,糾正錯誤並重新運行調試過程?如果存在這樣一種糾正錯誤的選項,那將是非常有用的。特別是對於需要很長運行時間的腳本,您必須從頭多次重複整個運行過程(如果出現很多錯誤)。

例如:

#!/bin/bash 

set -x # debugging 
trap read debug 

a="1" # wrong value, should be 2 
b="5" 
sum=$(bc <<< "$a + $b") 

set +x 

上述腳本具有一個陷阱以一次執行一行代碼和按壓輸入之後繼續到下一行。 在調試假設我意識到,一個= 1,但應該是別的東西可以說,A = 2。下一個命令b = 5,由於陷阱還沒有執行,所以我想到了在a = 1之下插入a = 2,然後繼續執行以繼續調試。

喜歡的東西下面的代碼:

#!/bin/bash 

set -x # debugging 
trap read debug 

a="1" # wrong value, should be 2 
a="2" # <-This is the value that a should have 
b="5" 
sum=$(bc <<< "$a + $b") 

set +x 

這種方法是行不通的,我猜是因爲整個腳本僅在運行的開始調用。在shell腳本中處理這樣一個問題的好方法是什麼?

謝謝

回答

2

只是充實您的解析器位:

#!/bin/bash 

function parser { 
    IFS= read -r input 
    printf "Going to do: >%s\n" $input 
    eval "$input" 
} 

set -x # debugging 
trap "parser" debug 

a="1" 
b="5" 
sum=$(bc <<< "$a + $b") 
set +x 

這當然只是一個襯墊的工作,但應該讓你開始。當你看到的調試是a=1(你會看到它在屏幕上),你可以只輸入a=3return。在所有其他線路上擊中return - 您將在sum處看到效果。

請注意,在此方法中(在調試中看到該行後重寫),始終運行AFTER錯誤的命令已運行,因爲這是調試器輸出它的時間。如果您想在運行之前查看命令,請在您的解析器中使用

echo $BASH_COMMAND 

。當然,在運行前a=10a=1有點適得其反。

例如改善可在解析,並跳過回聲,如果沒有收到輸入關閉調試:

function parser { 
    set +x 
    IFS= read -r input 
    if ! [ -z "$input" ]; then 
     printf "Going to do: >%s\n" $input 
     eval "$input" 
    fi 
    set -x 
} 

注意這不會修改腳本本身。要修改腳本本身就需要添加一個sed命令以及實際修改劇本,或者是呼應每行一個新的文件,如果收到與調試新的輸入替換 - 這是更安全的選擇。這可以爲這樣做(注意解析器運行後線已經跑了,所以我們總是輸出前面的命令,並在需要時將其覆蓋):

你的想象力是這裏的限制。和語法。我會將你的解析器移動到一個單獨的文件中,並根據需要提供它。

答案在註釋問題,以便

  1. 注意我有echo $prev_cmd >> debug_log.bash。如果您以前沒有設置過,則第一次調用解析器時,​​將爲空。由於shebang肯定不會被調試,所以不會存在於您的新文件中,因此將第一行轉儲到新文件是一個很好的初始選擇 - 無論如何它都需要它。無論你喜歡什麼,你當然可以將其設置爲空或進行一些評論。

  2. 當您進入調試功能時,打開了調試(按定義)。爲了防止在調試器中進行調試,我關閉了它。最後,當離開函數時,我需要重新激活它,以便繼續調試。這就是爲什麼訂單被「反轉」到文件 - 它會關閉您的初始激活,並在繼續之前重新激活。

  3. 如果您想在sum=...之前停止調試,請在之前放置set +x - 這就是關閉調試的原因。就像我在解析器中所做的一樣。

致謝:特別感謝查爾斯·達菲爲使代碼更安全的使用。只是更好。

+0

你能詳細說一下'set prev_cmd =「#!/ bin/bash」'是做什麼的? – athanell

+0

我還注意到用於包含調試區域的'set -x'和'set + x'的序列在函數解析器(您的第二個示例)中反向,但我不明白爲什麼。 – athanell

+0

最後,我想問問某人(在使用您提供的第二種或第三種方法時)是否可以包含要調試和糾正的部分腳本。因此,假設在命令'sum = $(bc <<<「$ a + $ b」)'下面是其他代碼行,並且我想包含調試代碼直到sum變量。謝謝@kabanus提供了非常有幫助的答案 – athanell