ในบทความของซีรีส์การดีบักเชลล์สคริปต์ เราจะอธิบายโหมดดีบักเชลล์สคริปต์ที่สาม นั่นคือการติดตามเชลล์และดูตัวอย่างเพื่อสาธิตวิธีการทำงานและวิธีใช้งาน
ส่วนก่อนหน้าของซีรีส์นี้ให้ความกระจ่างชัดเกี่ยวกับโหมดดีบักเชลล์สคริปต์อีกสองโหมด:โหมด verbose และ การตรวจสอบไวยากรณ์ โหมดพร้อมตัวอย่างที่เข้าใจง่ายเกี่ยวกับวิธีการเปิดใช้งานการดีบักเชลล์สคริปต์ในโหมดเหล่านี้
- วิธีเปิดใช้งานโหมดดีบักเชลล์สคริปต์ใน Linux – ตอนที่ 1
- วิธีดำเนินการตรวจสอบไวยากรณ์โหมดดีบักในเชลล์สคริปต์ – ตอนที่ 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 ส่วน