Cara Melacak Eksekusi Perintah di Shell Script dengan Shell Tracing


Dalam artikel seri debugging skrip shell ini, kami akan menjelaskan mode debugging skrip shell ketiga, yaitu penelusuran shell dan melihat beberapa contoh untuk mendemonstrasikan cara kerjanya, dan cara penggunaannya.

Bagian sebelumnya dari seri ini dengan jelas menyoroti dua mode debugging skrip shell lainnya: mode mode verbose dan mode pemeriksaan sintaksis dengan contoh yang mudah dipahami tentang cara mengaktifkan shell skrip debugging dalam mode ini.

  1. Cara Mengaktifkan Mode Debugging Skrip Shell di Linux – Bagian 1
  2. Cara Melakukan Mode Debugging Pemeriksaan Sintaks di Skrip Shell – Bagian 2

Pelacakan shell berarti menelusuri eksekusi perintah dalam skrip shell. Untuk mengaktifkan penelusuran shell, gunakan opsi debugging -x.

Ini mengarahkan shell untuk menampilkan semua perintah dan argumennya di terminal saat dieksekusi.

Kami akan menggunakan skrip shell sys_info.sh di bawah ini, yang secara singkat mencetak tanggal dan waktu sistem Anda, jumlah pengguna yang login, dan waktu aktif sistem. Namun, ini mengandung kesalahan sintaksis yang perlu kita temukan dan perbaiki.

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

Simpan file dan buat skrip dapat dieksekusi. Script hanya dapat dijalankan dengan root, oleh karena itu gunakan perintah sudo untuk menjalankannya seperti di bawah ini:

chmod +x sys_info.sh
sudo bash -x sys_info.sh

Dari keluaran di atas kita dapat mengamati bahwa, suatu perintah dijalankan terlebih dahulu sebelum keluarannya diganti dengan nilai suatu variabel.

Misalnya, tanggal pertama kali dieksekusi dan outputnya diganti dengan nilai variabel DATE.

Kita dapat melakukan pemeriksaan sintaksis untuk hanya menampilkan kesalahan sintaksis sebagai berikut:

sudo bash -n sys_info.sh 

Jika kita melihat skrip shell secara kritis, kita akan menyadari bahwa pernyataan if tidak memiliki kata penutup fi. Oleh karena itu, mari kita tambahkan dan skrip baru sekarang akan terlihat seperti di bawah ini:

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

Simpan file lagi dan aktifkan sebagai root dan lakukan beberapa pemeriksaan sintaksis:

sudo bash -n sys_info.sh

Hasil operasi pemeriksaan sintaksis kami di atas masih menunjukkan bahwa masih ada satu bug lagi pada skrip kami di baris 21. Jadi, kami masih memiliki beberapa koreksi sintaksis yang harus dilakukan.

Jika kita melihat skrip secara analitis sekali lagi, kesalahan pada baris 21 disebabkan oleh hilangnya tanda kutip ganda penutup ( ”) pada perintah echo terakhir di dalam print_sys_info fungsi.

Kami akan menambahkan tanda kutip ganda penutup pada perintah echo dan menyimpan file. Skrip yang diubah ada di bawah:

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

Sekarang periksa skrip secara sintaksis sekali lagi.

sudo bash -n sys_info.sh

Perintah di atas tidak akan menghasilkan output apa pun karena skrip kita sekarang sudah benar secara sintaksis. Kita juga dapat melacak eksekusi skrip untuk kedua kalinya dan itu akan berfungsi dengan baik:

sudo bash -x sys_info.sh

Sekarang jalankan skripnya.

sudo ./sys_info.sh

Pentingnya Pelacakan Eksekusi Skrip Shell

Penelusuran skrip shell membantu kami mengidentifikasi kesalahan sintaksis dan yang lebih penting, kesalahan logika. Ambil contoh fungsi check_root pada skrip shell sys_info.sh, yang dimaksudkan untuk menentukan apakah pengguna adalah root atau tidak, karena skrip hanya diperbolehkan untuk dieksekusi oleh pengguna super.

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

Keajaiban di sini dikendalikan oleh ekspresi if statement [ "$UID" -ne "$ROOT_ID" ], setelah kita tidak menggunakan operator numerik yang sesuai ( -ne dalam hal ini, yang artinya tidak sama ), kita akan mendapatkan kemungkinan kesalahan logika.

Dengan asumsi bahwa kita menggunakan -eq (berarti sama dengan), ini akan mengizinkan pengguna sistem mana pun serta pengguna root untuk menjalankan skrip, sehingga terjadi kesalahan logika.

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

Catatan: Seperti yang telah kita lihat sebelumnya di awal seri ini, perintah bawaan set shell dapat mengaktifkan debugging di bagian tertentu dari skrip shell.

Oleh karena itu, baris di bawah ini akan membantu kita menemukan kesalahan logika ini dalam fungsi dengan menelusuri eksekusinya:

Skrip dengan kesalahan logis:

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

Simpan file dan jalankan skripnya, kita dapat melihat bahwa pengguna sistem biasa dapat menjalankan skrip tanpa sudo seperti pada output di bawah ini. Hal ini karena nilai USER_ID adalah 100 yang tidak sama dengan root ROOT_ID yaitu 0.

./sys_info.sh

Baiklah, itu saja untuk saat ini, kita telah sampai pada akhir dari seri debugging skrip shell, formulir respons di bawah ini dapat digunakan untuk menjawab pertanyaan atau umpan balik apa pun kepada kami, mengenai panduan ini atau keseluruhan seri 3 bagian.