Trong bài viết này của loạt bài viết về gỡ lỗi tập lệnh shell, chúng tôi sẽ giải thích chế độ gỡ lỗi tập lệnh shell thứ ba, đó là theo dõi trình bao và xem xét một số ví dụ để chứng minh cách nó hoạt động và cách nó có thể được sử dụng.
Phần trước của loạt bài này rõ ràng đưa ra ánh sáng về hai chế độ gỡ lỗi tập lệnh shell khác: chế độ tiết và kiểm tra cú pháp chế độ với các ví dụ dễ hiểu về cách bật gỡ lỗi tập lệnh shell trong các chế độ này.
- Cách Bật Chế độ Gỡ lỗi Tập lệnh Shell trong Linux - Phần 1
- Cách thực hiện chế độ gỡ lỗi kiểm tra cú pháp trong tập lệnh Shell - Phần 2
Shell tracing đơn giản có nghĩa là theo dõi việc thực thi các lệnh trong một tập lệnh shell. Để bật tính năng theo dõi vỏ, hãy sử dụng -x
tùy chọn gỡ lỗi.
Điều này hướng dẫn trình bao hiển thị tất cả các lệnh và đối số của chúng trên thiết bị đầu cuối khi chúng được thực thi.
Chúng tôi sẽ sử dụng sys_info.sh
shell script bên dưới, trong đó in ngắn gọn ngày và giờ hệ thống của bạn, số lượng người dùng đã đăng nhập và thời gian hoạt động của hệ thống. Tuy nhiên, nó chứa các lỗi cú pháp mà chúng tôi cần tìm và sửa.
#!/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
Lưu tệp và làm cho tập lệnh có thể thực thi được. Tập lệnh chỉ có thể được chạy bởi root, do đó hãy sử dụng lệnh sudo để chạy nó như sau:
$ chmod +x sys_info.sh $ sudo bash -x sys_info.sh
Từ kết quả đầu ra ở trên, chúng ta có thể thấy rằng, một lệnh được thực thi lần đầu tiên trước khi đầu ra của nó được thay thế bằng giá trị của một biến.
Ví dụ: ngày được thực thi lần đầu tiên và đầu ra của nó được thay thế bằng giá trị của biến DATE .
Chúng tôi có thể thực hiện kiểm tra cú pháp để chỉ hiển thị các lỗi cú pháp như sau:
$ sudo bash -n sys_info.sh
Nếu chúng ta xem xét kịch bản shell một cách nghiêm túc, chúng ta sẽ nhận ra rằng if statement
thiếu fi
đóng từ. Do đó, hãy để chúng tôi thêm nó và tập lệnh mới bây giờ sẽ trông giống như bên dưới:
#!/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
Lưu tệp một lần nữa và gọi nó dưới dạng gốc và thực hiện một số kiểm tra cú pháp:
$ sudo bash -n sys_info.sh
Kết quả của thao tác kiểm tra cú pháp của chúng tôi ở trên vẫn cho thấy rằng có một lỗi nữa trong tập lệnh của chúng tôi trên dòng 21 . Vì vậy, chúng tôi vẫn phải sửa một số cú pháp.
Nếu chúng tôi xem xét phân tích tập lệnh một lần nữa, thì lỗi trên dòng 21 là do thiếu dấu ngoặc kép đóng (”)
trong lệnh echo cuối cùng bên trong print_sys_info
chức năng.
Chúng tôi sẽ thêm dấu ngoặc kép kết thúc trong echo lệnh và lưu tệp. Tập lệnh đã thay đổi ở bên dưới:
#!/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
Bây giờ, hãy kiểm tra cú pháp một lần nữa về kịch bản.
$ sudo bash -n sys_info.sh
Lệnh trên sẽ không tạo ra bất kỳ đầu ra nào vì tập lệnh của chúng ta hiện đã đúng về mặt cú pháp. Chúng tôi cũng có thể theo dõi việc thực thi tất cả tập lệnh lần thứ hai và nó sẽ hoạt động tốt:
$ sudo bash -x sys_info.sh
Bây giờ hãy chạy tập lệnh.
$ sudo ./sys_info.sh
Tầm quan trọng của việc theo dõi thực thi tập lệnh Shell
Việc truy tìm tập lệnh Shell giúp chúng ta xác định các lỗi cú pháp và quan trọng hơn là các lỗi logic. Ví dụ:check_root
trong sys_info.sh
shell script, nhằm xác định xem người dùng có phải là root hay không, vì script chỉ được phép thực thi bởi superuser.
check_root(){ if [ "$UID" -ne "$ROOT_ID" ]; then echo "You are not allowed to execute this program!" exit 1; fi }
Điều kỳ diệu ở đây được điều khiển bởi câu lệnh if statement
biểu thức [ "$UID" -ne "$ROOT_ID" ]
, khi chúng tôi không sử dụng toán tử số thích hợp (-ne
trong trường hợp này, có nghĩa là không bằng nhau), chúng tôi kết thúc với một lỗi lôgic có thể xảy ra.
Giả sử rằng chúng tôi đã sử dụng -eq
(có nghĩa là bằng), điều này sẽ cho phép bất kỳ người dùng hệ thống nào cũng như người dùng root chạy tập lệnh, do đó sẽ xảy ra lỗi logic.
check_root(){ if [ "$UID" -eq "$ROOT_ID" ]; then echo "You are not allowed to execute this program!" exit 1; fi }
Lưu ý :Như chúng ta đã xem xét trước ở phần đầu của loạt bài này, lệnh tích hợp shell set có thể kích hoạt gỡ lỗi trong một phần cụ thể của tập lệnh shell.
Do đó, dòng bên dưới sẽ giúp chúng tôi tìm ra lỗi logic này trong hàm bằng cách theo dõi việc thực thi của nó:
Tập lệnh có lỗi logic:
#!/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
Lưu tệp và gọi tập lệnh, chúng ta có thể thấy rằng người dùng hệ thống thông thường có thể chạy tập lệnh mà không cần sudo như trong đầu ra bên dưới. Điều này là do giá trị của USER_ID là 100 không bằng với gốc ROOT_ID cái nào là 0 .
$ ./sys_info.sh
Vâng, đó là bây giờ, chúng ta đã đến phần cuối của loạt bài viết gỡ lỗi shell script, biểu mẫu phản hồi bên dưới có thể được sử dụng để giải quyết bất kỳ câu hỏi hoặc phản hồi nào cho chúng tôi, liên quan đến hướng dẫn này hoặc toàn bộ chuỗi 3 phần.