1. 程式人生 > >在 Shell 指令碼中跟蹤除錯命令的執行

在 Shell 指令碼中跟蹤除錯命令的執行

shell 指令碼除錯系列

本系列的前面部分清晰地闡明瞭另外兩種 shell 指令碼除錯模式:詳細模式和語法檢查模式,並用易於理解的例子展示瞭如何在這些模式下啟用 shell 指令碼除錯。

概述

shell 跟蹤簡單的來說就是跟蹤 shell 指令碼中的命令的執行。要開啟 shell 跟蹤,請使用 -x 除錯選項。

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

終端版本

[[email protected] ~]$ lsb_release -a
LSB Version:    :base-4.0-amd64:base-4.0-noarch:core-4
.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch Distributor ID: CentOS Description: CentOS release 6.5 (Final) Release: 6.5 Codename: Final [[email protected] ~]$

我們將使用下面的 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

注: 在Linux中可以通過 $UID獲取 當前使用者的id ,root使用者的uid 為0

儲存檔案並執行指令碼。指令碼只能用 root 使用者執行,因此如下使用 sudo 命令執行:

讓普通使用者xgj具有root的所有許可權
執行vim /etc/sudoers之後,可以看見預設只有一條配置:
root ALL=(ALL) ALL
那麼你就在下邊再加一條配置:
xgj ALL=(ALL) ALL
這樣,普通使用者xgj 就能夠執行root許可權的所有命令

[xgj@entel2 shells]$  chmod +x sys_info.sh
[xgj@entel2 shells]$ sudo /bin/bash -x sys_info.sh 

這裡寫圖片描述

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

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

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

$ sudo bash -n sys_info.sh 

這裡寫圖片描述

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

#!/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;
  fi    
}
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 bash -n sys_info.sh

這裡寫圖片描述

再一次檢查語法。

$ sudo bash -n sys_info.sh

上面的命令不會產生任何輸出,因為我們的指令碼語法上正確。我們也可以再次跟蹤指令碼執行,它應該工作得很好:

$ sudo /bin/bash -x sys_info.sh

這裡寫圖片描述

現在執行指令碼。

$ sudo ./sys_info.sh

這裡寫圖片描述

shell 跟蹤執行的重要性

hell 指令碼跟蹤可以幫助我們識別語法錯誤,更重要的是識別邏輯錯誤。例如,在 sys_info.sh shell 指令碼中的 check_root 函式,它用於確定使用者是否為 root,因為指令碼只允許由超級使用者執行。

check_root(){
  if [ "$UID" -ne "$ROOT_ID" ]; then
    echo "You are not allowed to execute this program!"
    exit 1;
  fi
}

這裡的check_root由 if 語句表示式 ["$ UID" -ne "$ ROOT_ID"] 控制的,一旦我們不使用合適的數字運算子(示例中為 -ne,這意味著不相等),我們最終可能會出一個邏輯錯誤。

假設我們使用 -eq (意思是等於),這將允許任何系統使用者以及 root 使用者執行指令碼,因此是一個邏輯錯誤。

check_root(){
  if [ "$UID" -eq "$ROOT_ID" ]; then
    echo "You are not allowed to execute this program!"
    exit 1;
  fi
}

注意:我們在本系列開頭介紹過,set 這個 shell 內建命令可以在 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" -eq "$ROOT_ID" ]; then
    echo "You are not allowed to execute this program!"
    exit 1;
  fi
}
print_sys_info(){
  echo "System Time    : $DATE"
  echo "Number of users: $NO_USERS"
  echo "System Uptime  : $UPTIME"
}
#turning on and off debugging of check_root function
set -x 
check_root
set +x 
print_sys_info
exit 0

儲存檔案並呼叫指令碼,在輸出中,我們可以看到一個普通系統使用者可以在未 sudo 的情況下執行指令碼。 這是因為 USER_ID 的值為 502,不等於為 0 的 root 的 ROOT_ID 。

$ ./sys_info.sh

這裡寫圖片描述

相關推薦

Shell 指令碼跟蹤除錯命令執行

shell 指令碼除錯系列 本系列的前面部分清晰地闡明瞭另外兩種 shell 指令碼除錯模式:詳細模式和語法檢查模式,並用易於理解的例子展示瞭如何在這些模式下啟用 shell 指令碼除錯。 概述 shell 跟蹤簡單的來說就是跟蹤 sh

shell指令碼使用ls命令的注意事項

請對比如下兩個測試: $ for i in `ls /etc`;do echo $i;done adjtime adobe appstream.conf arch-release asound.conf avahi bash.bash_logout bas

shell指令碼的grep命令引數使用方法介紹(轉載)

用‘grep’搜尋文字檔案如果您要在幾個文字檔案中查詢一字串,可以使用‘grep’命令。‘grep’在文字中搜索指定的字串。舉個例子:假設您正在‘/usr/src/linux/Documentation’目錄下搜尋帶字串‘magic’的檔案: $ grep magic /u

shell指令碼如何獲取命令的引數(2) ----處理命令引數

 1    找出選項     1.1 處理簡單選項             主要可以通過shfit工具對獲取的到$1變數對比程式允許的變數值判斷;   1.2  從引數中分離選項    一般

Shell 指令碼的檔名匹配和命令執行

理解下 shell 指令碼中的檔名匹配和命令執行的順序與結果。我們學習這個的目的是可以熟悉的在 shell 指令碼中寫出快速的找到檔案的命令。它可以匹配檔名中的任何字串,匹配檔名中的單個字元以及匹配檔名中的字母或數字符號。         首先我們來看看匹配檔案的符號

如何在 Shell 指令碼執行語法檢查除錯模式【轉】

我們開啟了 Shell 指令碼除錯系列文章,先是解釋了不同的除錯選項,下面介紹如何啟用 Shell 除錯模式。 寫完指令碼後,建議在執行指令碼之前先檢查指令碼中的語法,而不是檢視它們的輸出以確認它們是否正常工作。 在本系列的這一部分,我們將瞭解如何使用語法檢查除錯模式

linux的shell指令碼執行多個命令的方法

第一種是以分號(;)進行劃分:表示:各命令的執行的果,不會影響其它命令的執行。換句話說,各個命令都會執行,但不保證每個命令都執行成功。 第二種命令之間&&隔開 表示:若前面的命令執

shell 指令碼獲取執行系統命令的輸出結果

這個主要介紹的方法是獲取命令的輸出內容,而不是命令執行成功與否的返回值。通常情況下,在shell指令碼中需要獲取命令的輸出內容,然後根據輸出內容判斷下一步的執行操作。比較常用的一種方式就是, 匹配命令輸出的內容中是否存在某些關鍵字,選擇執行的不同動作。比較常用的一種方式就是採

十六週二次課 2018.02.05 shell指令碼介紹、shell指令碼結構和執行、date命令用法、shell指令碼的變數

20.1 shell指令碼介紹微信公眾號部落格,20.2 shell指令碼結構和執行建立目錄,然後我們進去在裡面寫指令碼第一行是他表示接下來的命令是通過這一個直譯器操作解析的的,通常都是/bin/bash(如果你是在本機上執行那麼不用寫也行,因為它知道接下來的命令能夠在這臺機

Shell】關於shell指令碼執行cd命令無效的分析

###Date: 2017/1/7 ###Author: SoaringLee ###Content:關於shell指令碼中執行cd命令無效的分析 ===========================================================

20.1 shell指令碼介紹 20.2 shell指令碼結構和執行 20.3 date命令用法 20.4 shell指令碼的變數

20.1 shell指令碼介紹20.2 shell指令碼結構和執行20.3 date命令用法20.4 shell指令碼中的變數shell指令碼介紹shell是一種指令碼語言可以使用邏輯判斷、迴圈等語法可以自定義函式shell是系統命令的集合shell指令碼可以實現自動化運維,

Linux shell指令碼執行命令結果賦值給變數&&echo輸出變數是否包含換行符的問題

Linux shell指令碼中執行命令結果賦值給變數&&echo輸出變數是否包含換行符的問題 echo $ret 和 echo "$ret" 區別: 如果是echo $ret,輸出結果為一行,沒有換行符 如果是echo "$ret",輸出結果為多行,有換行符

shell指令碼賦值給變數有空格, 導致命令執行失敗

功能需求 統計指定時間程式傳送的資料量(按照發送時間) 傳送時間格式2017-12-14 16:18:11, 本來向獲取小時格式 date +'%Y-%m-%d %H' --date="-

shell指令碼順序執行另幾條shell命令

命令執行操作符 多條命令可以在一行中出現。它們可以從左到右順序執行。此時,各條命令之間應以分號( ;)隔開. 如:    pwd ; who | wc -l ; cd /usr/bin 在相鄰命令間可存在邏輯關係,即邏輯“與”和邏輯“或”。 邏輯與操作符“&&

什麼是shellshell指令碼結構和執行、date命令shell指令碼變數

開發十年,就只剩下這套架構體系了! >>>   

Shell 指令碼執行mysql語句

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Shell指令碼併發執行緒以及併發數的控制

http://blog.chinaunix.net/uid-8478094-id-3995108.html Shell指令碼中併發執行緒以及併發數的控制 主要記錄一下Shell指令碼中的命令的併發和序列執行。 預設的情況下,Shell指令碼中的命令是序列執行的,必須等到前一條命令

shell 指令碼獲取命令的輸出

這個主要介紹的方法是獲取命令的輸出內容,而不是命令執行成功與否的返回值。 通常情況下,在shell指令碼中需要獲取命令的輸出內容,然後根據輸出內容判斷下一步的執行操作。 比較常用的一種方式就是, 匹配命令輸出的內容中是否存在某些關鍵字,選擇執行的不同動作。 比較常用的一種方式就是

解決 shell指令碼SCP命令需要輸入密碼的問題

本文轉自:https://blog.csdn.net/u012454773/article/details/72779439 使用金鑰檔案,兩臺機器建立信任 這裡假設主機A(192.168.100.3)用來獲得主機B(192.168.100.4)的檔案。 在主機A上執行如下命令來生成配對金鑰:

解決命令執行shell指令碼成功,但crontab執行失敗

命令列執行指令碼成,但crontab執行shell指令碼不成功是由於兩個原因導致 解決方法 1. 路徑問題 檢視crontab中執行該指令碼的路徑是否正確。例如: */1 * * * * cd /mypath/;./my_shell.sh > /d