天天看點

如何在Shell腳本中跟蹤調試指令的執行

在 shell 腳本調試系列 中,本文将解釋第三種 shell 腳本調試模式,即 shell 跟蹤,并檢視一些示例來示範它如何工作以及如何使用它。

本系列的前面部厘清晰地闡明了另外兩種 shell 腳本調試模式:詳細模式和文法檢查模式,并用易于了解的例子展示了如何在這些模式下啟用 shell 腳本調試。

如何在 linux 中啟用 shell 腳本的調試模式

如何在 shell 腳本中執行文法檢查調試模式

shell 跟蹤簡單的來說就是跟蹤 shell 腳本中的指令的執行。要打開 shell 跟蹤,請使用 -x 調試選項。

這會讓 shell 在終端上顯示所有執行的指令及其參數。

我們将使用下面的 sys_info.sh shell 腳本,它會簡要地列印出你的系統日期和時間、登入的使用者數和系統的運作時間。不過,腳本中包含我們需要查找和更正的文法錯誤。

#!/bin/bash 

# script to print brief system info 

root_id="0" 

date=`date` 

no_users=`who | wc -l` 

uptime=`uptime` 

check_root(){ 

  if [ "$uid" -ne "$root_id" ]; then 

    echo "you are not allowed to execute this program!" 

    exit 1;     

print_sys_info(){ 

  echo "system time    : $date" 

  echo "number of users: $no_users" 

  echo "system uptime  : $uptime 

check_root 

print_sys_info 

exit 0 

儲存檔案并執行腳本。腳本隻能用 root 使用者運作,是以如下使用 sudo 指令運作:

$ chmod +x sys_info.sh 

$ sudo bash -x sys_info.sh    

如何在Shell腳本中跟蹤調試指令的執行

shell 跟蹤 - 顯示腳本中的錯誤

從上面的輸出我們可以觀察到,首先執行指令,然後其輸出做為一個變量的值。

例如,先執行 date,其輸出做為變量 date 的值。

我們可以執行文法檢查來隻顯示其中的文法錯誤,如下所示:

$ sudo bash -n sys_info.sh  

如何在Shell腳本中跟蹤調試指令的執行

腳本中文法檢查

如果我們審視這個 shell 腳本,我們就會發現 if 語句缺少了封閉條件的 fi 關鍵字。是以,讓我們加上它,新的腳本應該看起來像這樣:

#script to print brief system info 

    exit 1; 

  fi     

  echo "system time    : $date"  

再次儲存檔案并以 root 執行,同時做文法檢查:

如何在Shell腳本中跟蹤調試指令的執行

在 shell 腳本中執行文法檢查

上面的文法檢查操作的結果仍然顯示在腳本的第 21 行還有一個錯誤。是以,我們仍然要糾正一些文法。

再一次分析腳本,會發現第 21 行的錯誤是由于在 print_sys_info 函數内最後一個 echo 指令中沒有閉合雙引号 "。

我們将在 echo 指令中添加閉合雙引号并儲存檔案。修改過的腳本如下:

  fi 

  echo "system uptime  : $uptime" 

現在再一次檢查文法。

$ sudo bash -n sys_info.sh 

上面的指令不會産生任何輸出,因為我們的腳本文法上正确。我們也可以再次跟蹤腳本執行,它應該工作得很好:

$ sudo bash -x sys_info.sh  

如何在Shell腳本中跟蹤調試指令的執行

跟蹤 shell 腳本執行

現在運作腳本。

$ sudo ./sys_info.sh  

如何在Shell腳本中跟蹤調試指令的執行

用 shell 腳本顯示日期、時間和運作時間

shell 跟蹤執行的重要性

shell 腳本跟蹤可以幫助我們識别文法錯誤,更重要的是識别邏輯錯誤。例如,在 sys_info.sh shell 腳本中的 check_root 函數,它用于确定使用者是否為 root,因為腳本隻允許由超級使用者執行。

這裡的魔法是由 if 語句表達式 ["$ uid" -ne "$ root_id"] 控制的,一旦我們不使用合适的數字運算符(示例中為 -ne,這意味着不相等),我們最終可能會出一個邏輯錯誤。

假設我們使用 -eq (意思是等于),這将允許任何系統使用者以及 root 使用者運作腳本,是以是一個邏輯錯誤。

  if [ "$uid" -eq "$root_id" ]; then 

注意:我們在本系列開頭介紹過,set 這個 shell 内置指令可以在 shell 腳本的特定部分激活調試。

是以,下面的行将幫助我們通過跟蹤腳本的執行在其中找到這個邏輯錯誤:

具有邏輯錯誤的腳本:

#turning on and off debugging of check_root function 

set -x ; check_root;  set +x ; 

儲存檔案并調用腳本,在輸出中,我們可以看到一個普通系統使用者可以在未 sudo 的情況下運作腳本。 這是因為 user_id 的值為 100,不等于為 0 的 root 的 root_id 。

$ ./sys_info.sh  

如何在Shell腳本中跟蹤調試指令的執行

run shell script without sudo

未 sudo 的情況下運作 shell 腳本

那麼,現在我們已經完成了 shell 腳本調試系列,可以在下面的回報欄裡給我們關于本篇或者本系列提出問題或回報。

作者簡介:

如何在Shell腳本中跟蹤調試指令的執行

aaron kili 是 linux 和 f.o.s.s 愛好者,将來的 linux sysadmin、web 開 發人員,目前是 tecmint 的内容創作者,他喜歡用電腦工作,并堅信分享知識。

作者:aaron kili

來源:51cto

繼續閱讀