Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม BASH

วิธีติดตามการดำเนินการคำสั่งในเชลล์สคริปต์ด้วยการติดตามเชลล์

ในบทความของซีรีส์การดีบักเชลล์สคริปต์ เราจะอธิบายโหมดดีบักเชลล์สคริปต์ที่สาม นั่นคือการติดตามเชลล์และดูตัวอย่างเพื่อสาธิตวิธีการทำงานและวิธีใช้งาน

ส่วนก่อนหน้าของซีรีส์นี้ให้ความกระจ่างชัดเกี่ยวกับโหมดดีบักเชลล์สคริปต์อีกสองโหมด:โหมด verbose และ การตรวจสอบไวยากรณ์ โหมดพร้อมตัวอย่างที่เข้าใจง่ายเกี่ยวกับวิธีการเปิดใช้งานการดีบักเชลล์สคริปต์ในโหมดเหล่านี้

  1. วิธีเปิดใช้งานโหมดดีบักเชลล์สคริปต์ใน Linux – ตอนที่ 1
  2. วิธีดำเนินการตรวจสอบไวยากรณ์โหมดดีบักในเชลล์สคริปต์ – ตอนที่ 2

การติดตามเชลล์หมายถึงการติดตามการดำเนินการของคำสั่งในเชลล์สคริปต์ หากต้องการเปิดการติดตามเชลล์ ให้ใช้ -x ตัวเลือกการดีบัก

คำสั่งนี้กำหนดให้เชลล์แสดงคำสั่งทั้งหมดและอาร์กิวเมนต์บนเทอร์มินัลขณะที่ดำเนินการ

เราจะใช้ sys_info.sh เชลล์สคริปต์ด้านล่าง ซึ่งพิมพ์วันที่และเวลาของระบบโดยสังเขป จำนวนผู้ใช้ที่เข้าสู่ระบบ และเวลาทำงานของระบบ อย่างไรก็ตาม มีข้อผิดพลาดทางไวยากรณ์ที่เราจำเป็นต้องค้นหาและแก้ไข

#!/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

บันทึกไฟล์และทำให้สคริปต์ทำงานได้ สคริปต์สามารถเรียกใช้โดยรูทเท่านั้น ดังนั้นให้ใช้คำสั่ง sudo เพื่อเรียกใช้ดังต่อไปนี้:

$ chmod +x sys_info.sh
$ sudo bash -x sys_info.sh
วิธีติดตามการดำเนินการคำสั่งในเชลล์สคริปต์ด้วยการติดตามเชลล์

จากผลลัพธ์ข้างต้น เราสามารถสังเกตได้ว่า คำสั่งจะถูกดำเนินการก่อนที่จะแทนที่ผลลัพธ์เป็นค่าของตัวแปร

ตัวอย่างเช่น วันที่ ถูกดำเนินการครั้งแรกและผลลัพธ์ถูกแทนที่เป็นค่าของตัวแปร DATE .

เราสามารถดำเนินการตรวจสอบไวยากรณ์เพื่อแสดงเฉพาะข้อผิดพลาดทางไวยากรณ์ดังนี้:

$ sudo bash -n sys_info.sh 
วิธีติดตามการดำเนินการคำสั่งในเชลล์สคริปต์ด้วยการติดตามเชลล์

หากเราพิจารณาเชลล์สคริปต์อย่างมีวิจารณญาณ เราจะพบว่าคำสั่ง if statement ขาด 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

บันทึกไฟล์อีกครั้งและเรียกใช้เป็นรูทและทำการตรวจสอบไวยากรณ์:

$ sudo bash -n sys_info.sh
วิธีติดตามการดำเนินการคำสั่งในเชลล์สคริปต์ด้วยการติดตามเชลล์

ผลลัพธ์ของการดำเนินการตรวจสอบไวยากรณ์ด้านบนยังคงแสดงให้เห็นว่ามีข้อบกพร่องอีกหนึ่งจุดในสคริปต์ของเราในบรรทัดที่ 21 . ดังนั้น เรายังมีการแก้ไขไวยากรณ์ที่ต้องทำ

หากเราวิเคราะห์สคริปต์อีกครั้ง ข้อผิดพลาดใน บรรทัดที่ 21 เกิดจากการปิดเครื่องหมายอัญประกาศ (”) ในคำสั่ง echo ล่าสุดภายใน print_sys_info ฟังก์ชัน

เราจะเพิ่มเครื่องหมายคำพูดปิดใน เสียงสะท้อน คำสั่งและบันทึกไฟล์ สคริปต์ที่เปลี่ยนแปลงอยู่ด้านล่าง:

#!/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

ตอนนี้ให้ตรวจสอบสคริปต์อีกครั้ง

$ sudo bash -n sys_info.sh

คำสั่งด้านบนจะไม่สร้างผลลัพธ์ใดๆ เนื่องจากตอนนี้สคริปต์ของเรามีไวยากรณ์ที่ถูกต้องแล้ว เราสามารถติดตามการทำงานของสคริปต์ทั้งหมดเป็นครั้งที่สองได้เช่นกัน และมันน่าจะทำงานได้ดี:

$ sudo bash -x sys_info.sh
วิธีติดตามการดำเนินการคำสั่งในเชลล์สคริปต์ด้วยการติดตามเชลล์ วิธีติดตามการดำเนินการคำสั่งในเชลล์สคริปต์ด้วยการติดตามเชลล์

ตอนนี้ให้รันสคริปต์

$ sudo ./sys_info.sh
วิธีติดตามการดำเนินการคำสั่งในเชลล์สคริปต์ด้วยการติดตามเชลล์ วิธีติดตามการดำเนินการคำสั่งในเชลล์สคริปต์ด้วยการติดตามเชลล์

ความสำคัญของการติดตามการดำเนินการเชลล์สคริปต์

การติดตามสคริปต์ของเชลล์ช่วยให้เราระบุข้อผิดพลาดทางไวยากรณ์และที่สำคัญกว่านั้นคือข้อผิดพลาดทางตรรกะ ยกตัวอย่าง check_root ฟังก์ชันใน sys_info.sh เชลล์สคริปต์ ซึ่งมีวัตถุประสงค์เพื่อกำหนดว่าผู้ใช้เป็นรูทหรือไม่ เนื่องจากสคริปต์ได้รับอนุญาตให้เรียกใช้งานโดยผู้ใช้ระดับสูงเท่านั้น

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

ความมหัศจรรย์ที่นี่ถูกควบคุมโดย if statement นิพจน์ [ "$UID" -ne "$ROOT_ID" ] เมื่อเราไม่ใช้ตัวดำเนินการตัวเลขที่เหมาะสม (-ne ในกรณีนี้ซึ่งหมายถึงไม่เท่ากัน ) เราลงเอยด้วยข้อผิดพลาดทางตรรกะที่เป็นไปได้

สมมติว่าเราใช้ -eq ( หมายถึงเท่ากับ) สิ่งนี้จะอนุญาตให้ผู้ใช้ระบบและผู้ใช้รูทสามารถเรียกใช้สคริปต์ได้ ดังนั้นจึงเป็นข้อผิดพลาดเชิงตรรกะ

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

หมายเหตุ :ดังที่เราได้ดูไปก่อนหน้านี้แล้วในตอนเริ่มต้นของซีรีส์นี้ คำสั่ง set 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 คือ 100 ซึ่งไม่เท่ากับรูท ROOT_ID ซึ่งก็คือ 0 .

$ ./sys_info.sh
วิธีติดตามการดำเนินการคำสั่งในเชลล์สคริปต์ด้วยการติดตามเชลล์

เท่านี้ก็เรียบร้อย สำหรับตอนนี้ เราได้มาถึงจุดสิ้นสุดของชุดการดีบักเชลล์สคริปต์แล้ว แบบฟอร์มตอบกลับด้านล่างสามารถใช้เพื่อตอบคำถามหรือข้อเสนอแนะใดๆ เกี่ยวกับคู่มือนี้หรือทั้งชุด 3 ส่วน