Menjadikan skrip Zsh tangguh terhadap kegagalan: menangkap sinyal dan error dengan trap (ERR/EXIT), memahami exit codes dan return codes, menghentikan skrip dengan errexit, lalu teknik debugging dengan zsh -x, zsh -n, print -P dan print -l, serta which -f untuk memeriksa definisi function

Setelah di episode 15 environment kalian tertata, pada episode ini kita membahas keterampilan yang memisahkan skrip "beruntung" dari skrip "andal": error handling dan debugging. Skrip yang tidak menangani kegagalan akan terus berjalan dengan kondisi rusak — backup setengah jadi, deploy setengah jalan, dan tidak ada satu pun yang melapor.
Di episode ini kita gabungkan dua hal: mencegah (trap, exit codes, errexit) dan menemukan (debugging dengan trace, syntax check, print). Dengan keduanya, kalian bisa memastikan skrip berhenti di tempat yang tepat, melaporkan masalah yang jelas, dan mudah ditelusuri saat ada yang salah.
Setiap perintah selesai dengan exit code: 0 sukses, non-zero gagal. Skrip juga bisa mengembalikan status lewat exit N (menghentikan proses) atau return N (keluar dari function).
check_file() {
if [[ ! -f "$1" ]]; then
print "File tidak ada: $1" >&2
return 2 # kode khusus untuk "file tidak ada"
fi
return 0
}
check_file /etc/hosts && print "OK"
print "exit=$?"Kesepakatan umum: kode 0-255, dan komunitas memakai kode spesifik (1 error umum, 2 usage salah, 126/127 command tidak ditemukan/dieksekusi). Konsistensi kode memudahkan caller menentukan penyebab.
Dari episode 11: errexit (atau set -e) menghentikan skrip saat perintah mengembalikan non-zero.
setopt errexit
rm -f /tmp/x
cp missing/file /tmp/ # gagal → skrip berhenti di sini
print "tidak akan dicetak"Jebakan yang perlu diwaspadai:
if cmd; then) tidak memicu exit.|| true dianggap aman.# Aman (kondisi):
if command_not_exist; then :; fi
# Aman (|| true):
command_not_exist || true
# AMAN juga, tapi pipeline: status = status terakhir
command_not_exist | cattrap menjalankan kode saat event tertentu terjadi. Yang paling berguna di skrip:
cleanup() {
print "Membersihkan temporary files..."
rm -rf "$TMPDIR"
}
trap cleanup EXIT
on_error() {
print "Error di line $LINENO, command: $?" >&2
}
trap on_error ERR| Sinyal/Event | Terjadi Ketika |
|---|---|
EXIT | Skrip/function selesai (sukses atau gagal) |
ERR | Perintah gagal (jika errexit mati, tetap dipanggil) |
INT | Pengguna menekan Ctrl-C |
TERM | kill dikirim |
DEBUG | Sebelum setiap perintah dijalankan |
trap 'print "Dibatalkan oleh user"; exit 1' INT
sleep 300Tip
Pattern produksi: trap cleanup EXIT untuk pembersihan + trap on_error ERR untuk laporan. Karena EXIT selalu dijalankan, temporary file dijamin bersih baik sukses maupun gagal — ini pengganti try/finally di bahasa lain.
print bawaan Zsh jauh lebih fleksibel daripada echo. Dua flag yang paling sering dipakai:
# -l: satu item per baris (list)
print -l a b c
# a
# b
# c
# -P: expand prompt escapes (episode 7)
print -P "%F{green}sukses%f"
print -P "%d" # direktori aktif
print -P "%n@%m" # user@host
# -n: tanpa newline
print -n "menunggu"
sleep 1
print " selesai"print -P sangat berguna untuk menguji prompt escapes sebelum menaruhnya di PROMPT, dan print -l untuk menampilkan array dengan rapi saat debug.
zsh -x mencetak setiap perintah sebelum dieksekusi (dengan + prefix), plus perluasan variabel:
zsh -x script.zsh
# +print 'Processing...'
# Processing...
# +rm -rf /tmp/x
# ...Untuk menelusuri function tertentu tanpa me-trace seluruh skrip, nyalakan lokal:
setopt xtrace
process() { ... }
process
setopt no_xtracezsh -n memeriksa sintaks tanpa menjalankan skrip — semacam "compile check":
zsh -n script.zsh && print "sintaks OK"Ini wajib di CI untuk skrip shell (episode 19). Kombinasi -n lalu -x adalah alur debugging standar: pastikan sintaks valid, baru telusuri logika.
zsh -v mencetak setiap baris sebelum dievaluasi (tanpa perluasan variabel) — berguna melihat struktur mentah skrip. Kombinasi zsh -xv paling lengkap.
Untuk memeriksa definisi function, alias, atau menemukan asal command:
which -f ensure_dir # tampilkan definisi function
functions ensure_dir # sama
which ensure_dir # cari asal (binary, alias, atau function)
which -a ls # semua kemungkinan definisiwhence -v ls # ls: alias ke 'ls --color=auto'
whence -w compinit # compinit: function
command -v rg # /usr/bin/rg (hanya binary)whence adalah tool Zsh untuk menelusuri asal sesuatu — setara type di bash tapi lebih detail. Ini menyelesaikan misteri "kenapa perintah saya beda": seringnya karena alias atau function yang menimpa binary.
unset — trap global tetap aktif di shell anak; panggil trap - ERR untuk melepas.set -e dengan function yang dipanggil di $(...) — kegagalan di command substitution bisa tidak terdeteksi; uji dengan setopt pipefail juga.xtrace di skrip produksi membocorkan detail; matikan dengan setopt no_xtrace.print vs echo — echo -e tidak standar antar shell; gunakan print yang konsisten di Zsh.Inti yang harus dibawa pulang:
setopt errexit menghentikan skrip saat gagal; pahami jebakan pipeline dan kondisi.trap cleanup EXIT + trap on_error ERR adalah pattern produksi untuk pembersihan dan laporan.zsh -x (trace), zsh -n (sintaks), print -P/print -l, whence/which -f.Di episode 17 selanjutnya kita akan membahas keamanan & best practice — menghindari eval pada input tak dipercaya, mengaktifkan nounset, melindungi skrip dari shell injection, disiplin quoting "$@", dan sanitasi environment sebelum privilege escalation. Sampai jumpa di episode 17!