Debug Shell Script di Linux Production: Teknik Cepat Menemukan Error Tanpa Bikin Panik
Pernah ngalamin script Bash yang “kemarin aman”, tapi pas jalan di server production malah error random?
Di laptop lancar. Di staging aman. Begitu masuk production: job gagal, log minim, dan kamu harus nebak-nebak error ada di mana. Ini kejadian klasik di dunia linux shell scripting.
Kabar baiknya, debugging shell script itu bisa dibuat sistematis. Jadi bukan lagi mode “coba-coba lalu berharap”. Di artikel ini kita bahas teknik praktis yang bisa langsung kamu pakai buat nemuin akar masalah lebih cepat, lebih rapi, dan lebih aman.
Kalau kamu mau fondasi script yang lebih stabil dulu, baca juga:
Kenapa script shell sering susah di-debug?
Masalah paling sering bukan karena Bash-nya “jelek”, tapi karena karakter shell script memang dekat banget sama environment OS. Sedikit beda context, hasil bisa beda jauh.
Contoh perbedaan yang sering bikin jebakan:
- PATH beda antara terminal interaktif vs cron/systemd
- Variable environment tidak ter-load
- Permission file/folder beda user
- Command external (
awk,sed,find) beda versi antar server - Race condition karena job overlap
Itu kenapa script automation perlu pendekatan debug yang terstruktur, apalagi kalau dipakai untuk automasi tugas linux di production.
Prinsip utama: jangan debug buta, debug terarah
Target kamu bukan “bikin error hilang sekali”, tapi:
- Cepat tahu titik gagal
- Tahu context kegagalan
- Punya log yang bisa diulang untuk investigasi
- Bisa mencegah kasus serupa kejadian lagi
Dengan pola ini, troubleshooting jadi lebih tenang dan repeatable.
1) Mulai dari strict mode + error trap yang jelas
Kalau script belum pakai strict mode, debugging bakal melelahkan karena error kecil bisa lewat diam-diam.
#!/usr/bin/env bash
set -Eeuo pipefail
IFS=$'\n\t'
on_error() {
local line="$1"
local cmd="$2"
local code="$3"
echo "[ERROR] line=$line cmd='$cmd' exit=$code"
}
trap 'on_error "${LINENO}" "${BASH_COMMAND}" "$?"' ERR
Kenapa ini penting?
-e: stop kalau ada command gagal-u: stop kalau variabel belum didefinisikanpipefail: pipeline gagal kalau salah satu command gagaltrap ERR: kasih konteks command mana yang gagal
Kalau kamu belum biasa, ini step paling impactful untuk bash scripting linux.
2) Aktifkan trace mode sementara (set -x) saat investigasi
Saat butuh lihat urutan command yang dieksekusi, pakai xtrace.
set -x
# blok yang mau diinvestigasi
run_backup
sync_artifact
set +x
Biar output trace lebih informatif, set PS4:
export PS4='+ [${BASH_SOURCE}:${LINENO}] ${FUNCNAME[0]:-main}() '
set -x
Output trace jadi nunjukkin file + line number. Ini sangat ngebantu kalau script kamu panjang atau banyak function.
Tips production: jangan nyalain set -x terus-menerus kalau script memproses secret (token/password). Aktifkan hanya di blok aman.
3) Selalu log ke file + timestamp
Debug tanpa timestamp itu bikin pusing saat nyocokin dengan event lain (mis. restart service, spike CPU, atau network issue).
Template logging sederhana:
LOG_FILE="/var/log/myjob.log"
log() {
echo "[$(date '+%F %T')] $*" | tee -a "$LOG_FILE"
}
log "job started"
Untuk job terjadwal (cron/systemd), logging ini wajib banget. Kalau pakai systemd timer, kamu juga bisa review lewat journalctl.
Relevan: Systemd Timer vs Cron untuk Automasi Linux Production
4) Verifikasi environment runtime (bukan asumsi)
Banyak bug muncul karena script mengasumsikan environment tertentu.
Di awal script, validasi hal-hal penting:
required_cmds=(curl jq awk sed)
for cmd in "${required_cmds[@]}"; do
command -v "$cmd" >/dev/null || {
echo "[FATAL] command tidak ditemukan: $cmd"
exit 1
}
done
: "${APP_ENV:?APP_ENV wajib di-set}"
: "${API_URL:?API_URL wajib di-set}"
Gunakan absolute path jika perlu (/usr/bin/curl) supaya tidak tergantung PATH dinamis.
5) Gunakan ShellCheck untuk deteksi bug statis
Sebelum script jalan di server, lint dulu.
shellcheck deploy.sh
ShellCheck sering nemuin masalah yang luput dari mata:
- variabel tidak di-quote
- word splitting berbahaya
- test condition ambigu
- typo yang “valid” tapi salah logic
Ini cara murah untuk mencegah incident.
6) Debug command eksternal dengan strace (kalau mentok)
Kalau script bilang command gagal tapi gak jelas kenapa, strace bisa bantu lihat syscall level (file apa yang dicari, permission denied, koneksi gagal, dll).
strace -f -o /tmp/trace.log bash ./deploy.sh
Fokus cari:
ENOENT(file/command tidak ditemukan)EACCES(permission denied)- timeout atau koneksi ditolak
Memang lebih teknis, tapi untuk kasus stubborn di production, ini sering jadi penyelamat.
7) Hindari job overlap dengan lock (flock)
Kadang error bukan karena logic script, tapi karena script jalan barengan dua kali.
LOCK_FILE="/tmp/myjob.lock"
exec 9>"$LOCK_FILE"
if ! flock -n 9; then
echo "[INFO] job lain masih jalan, skip"
exit 0
fi
Tanpa lock, kamu bisa dapat gejala aneh: file korup, data dobel, atau proses saling timpa.
8) Pisahkan mode normal vs mode debug
Best practice yang sering dipakai tim ops: bikin flag debug.
DEBUG_MODE="${DEBUG_MODE:-0}"
if [[ "$DEBUG_MODE" == "1" ]]; then
export PS4='+ [${BASH_SOURCE}:${LINENO}] '
set -x
fi
Jadi saat incident kamu tinggal jalanin:
DEBUG_MODE=1 ./job.sh
Setelah selesai, balik ke mode normal tanpa ubah banyak kode.
9) Kasus nyata: “jalan manual sukses, jalan scheduler gagal”
Ini salah satu kasus paling sering.
Gejala
- Kalau dijalankan manual sebagai user A: sukses
- Kalau dijalankan dari cron/systemd: gagal
Akar masalah umum
- PATH scheduler minimal
- ENV var tidak kebaca
- Working directory beda
- Permission beda user service
Solusi praktis
- Pakai absolute path command
- Set env eksplisit di script/unit
cdke direktori kerja di awal script- Log output stderr/stdout
- Uji script dengan user yang sama seperti scheduler
Ini alasan kenapa desain script aman itu gak bisa dipisah dari observability.
10) Checklist debug cepat saat incident
Saat alert masuk, pakai urutan ini biar tidak panik:
- Cek timestamp failure terakhir
- Lihat command gagal + exit code
- Validasi env var wajib
- Validasi dependency command
- Cek permission file/folder target
- Jalankan ulang di mode debug (
DEBUG_MODE=1) - Jika masih mentok, pakai
strace - Dokumentasikan root cause + fix permanen
Urutan ini mempercepat MTTR (mean time to recovery) dan bikin penanganan lebih konsisten antar anggota tim.
Bonus: pola script yang lebih aman untuk production
Selain teknik debug, kualitas desain script juga penting. Pola minimum yang sebaiknya selalu ada:
- strict mode (
set -Eeuo pipefail) - trap error dengan konteks line/command
- logging timestamp
- lockfile anti-overlap
- validasi dependency + env var
- dry-run mode (kalau memungkinkan)
- rollback sederhana untuk operasi berisiko
Kalau kamu sering deploy service, kamu juga bisa adaptasi pola rollback dari artikel ini: linux incident response playbook practical troubleshooting and containment
Kapan harus stop pakai “script cepat-cepat”?
Script kecil itu oke. Tapi kalau sudah dipakai:
- lintas tim,
- menyentuh data penting,
- atau dieksekusi otomatis tiap hari,
maka script tersebut sudah masuk kategori production asset. Artinya, perlakukan seperti kode aplikasi: versioning, review, test, observability.
Ini juga nyambung ke keamanan. Script yang sulit di-debug biasanya juga sulit diaudit. Di lingkungan real, itu risk tambahan.
Terkait hardening server, kamu bisa lanjut baca:
- UFW vs Fail2Ban vs SSH Hardening: Kombinasi Keamanan Server Linux
- Linux Security Baseline Audit Checklist for Small Teams
FAQ
1) Apa perintah paling cepat untuk mulai debug shell script?
Mulai dari set -Eeuo pipefail + trap ERR, lalu aktifkan set -x di blok yang dicurigai. Ini sudah cukup untuk nemuin banyak bug umum.
2) Apakah set -x aman dipakai di production?
Aman kalau hati-hati. Hindari men-trace blok yang memproses secret (token/password), karena nilainya bisa ikut tercetak di log.
3) Kapan perlu pakai strace?
Pakai saat log Bash tidak cukup menjelaskan error, terutama jika terkait permission, file tidak ketemu, atau behavior command eksternal yang aneh.
4) Kenapa script sukses saat manual tapi gagal di cron/systemd?
Biasanya karena beda environment: PATH, env var, working directory, atau user permission. Makanya environment wajib divalidasi eksplisit.
5) Tool wajib untuk meningkatkan kualitas bash scripting linux apa?
Minimal: shellcheck, logging timestamp, strict mode, trap error, dan lockfile (flock). Kombinasi ini sudah bikin script jauh lebih tahan banting.
Intinya: debugging shell script di production itu bukan soal hafal command aja, tapi soal disiplin observability. Begitu kamu punya pola strict mode + trap + logging + lock, proses troubleshooting jadi jauh lebih cepat, minim tebak-tebakan, dan tidak bikin panik pas incident beneran.
Komentar
Memuat komentar...
Tulis Komentar