Skrip yang menjalankan baris yang sama berapa pun keadaannya belum bisa disebut program — baru rangkaian perintah. Percabanganlah yang mengubah rangkaian itu menjadi logika: jalankan backup hanya bila disk cukup, tampilkan pesan error hanya bila file tidak ada. Fondasinya sudah kita miliki sejak Chapter Exit Codes: setiap perintah melapor lewat exit code, dan if adalah cara bash bertanya “apakah laporannya nol?”. Chapter ini memakai laporan itu lewat if, membedah perintah test dengan seluruh operatornya, lalu merapikan percabangan banyak kasus dengan case.
if dan Perintah test #
Struktur if menjalankan sebuah perintah, lalu mengambil cabang then bila exit code-nya 0, atau cabang else bila bukan 0. Kata kunci penutup tiap blok adalah fi — if dieja terbalik. Skrip berikut memeriksa sebuah target, memakai operator file -f (file biasa) dan -d (direktori):
printf 'isi catatan\n' > catatan.txt
cat > cek.sh << 'AKHIR'
#!/bin/bash
target="$1"
if [ -f "$target" ]; then
echo "$target adalah file biasa"
elif [ -d "$target" ]; then
echo "$target adalah direktori"
else
echo "$target tidak ditemukan"
fi
AKHIR
bash cek.sh catatan.txt
bash cek.sh /tmp
bash cek.sh hilang.txtOutput yang Dihasilkan:
catatan.txt adalah file biasa
/tmp adalah direktori
hilang.txt tidak ditemukanVariabel target diisi dari $1 — argumen pertama saat skrip dipanggil; pembahasan lengkap argumen menunggu Chapter Arguments dan Command Line Options, dan penggunaan singkat seperti ini sudah cukup aman. Perhatikan pula tanda titik koma setelah [ ... ]: tanda itu memisahkan perintah uji dari kata kunci then yang harus berada di baris baru bila tanpa ;.
Tanda kurung [ bukan sekadar tanda baca — [ adalah nama lain dari perintah test, dan operatornya yang paling sering dipakai:
| Operator | Bernilai benar bila |
|---|---|
-e jalur | jalur ada (file atau direktori apa pun) |
-f jalur | jalur adalah file biasa |
-d jalur | jalur adalah direktori |
-z teks | teks kosong |
-n teks | teks tidak kosong |
Operator String dan Angka #
Perbandingan string dan angka memakai operator yang berbeda — bash menyimpan semua nilai sebagai string, sehingga test perlu diberi tahu maksud kita. String dibandingkan dengan = dan !=, sedangkan angka dengan keluarga -eq, -ne, -lt, -le, -gt, -ge:
nama="Budi"
umur=17
[ "$nama" = "Budi" ] && echo "nama cocok"
[ "$nama" != "Siti" ] && echo "bukan Siti"
[ "$umur" -ge 17 ] && echo "17 tahun atau lebih"
[ -n "$nama" ] && echo "nama terisi"Output yang Dihasilkan:
nama cocok
bukan Siti
17 tahun atau lebih
nama terisiMengapa tidak sekadar [ "$umur" > 17 ]? Perbandingan string mengurutkan karakter demi karakter, sehingga 10 dianggap lebih kecil dari 9 — sama seperti am mendahului b. Keluarga -eq seterusnya membandingkan sebagai bilangan dan bebas dari jebakan itu.
Kurung Tunggal [ vs Kurung Ganda [[ ]] #
Perintah test alias [ menerima argumen yang sudah dipecah dan diexpand bash — itulah akar masalah klasik berikut:
nama="Budi Santoso"
[ $nama = "Budi Santoso" ] 2>&1
echo "exit code [ : $?"
[[ $nama = "Budi Santoso" ]] && echo "[[ ]] : cocok"Output yang Dihasilkan:
bash: [: too many arguments
exit code [ : 2
[[ ]] : cocokTanpa kutip, nilai $nama pecah menjadi dua kata, sehingga [ menerima lima argumen dan menyerah dengan too many arguments serta exit code 2. Kurung ganda [[ ]] adalah kata kunci bash, bukan perintah: isinya tidak dipecah, mendukung ==, operator && dan || di dalamnya, serta pencocokan pola. Harga yang dibayar adalah portabilitas — [[ ]] hanya ada di bash dan kerabatnya, tidak di POSIX sh murni.
case untuk Banyak Cabang #
Rantai if-elif yang panjang sulit dibaca ketika tiap cabang membandingkan nilai yang sama. Struktur case mengevaluasi satu kata lalu mencocokkannya dengan pola, ditutup kata kunci esac:
cat > menu.sh << 'AKHIR'
#!/bin/bash
perintah="$1"
case "$perintah" in
mulai)
echo "menyalakan layanan"
;;
stop|hentikan)
echo "mematikan layanan"
;;
status)
echo "layanan sedang berjalan"
;;
*)
echo "perintah tidak dikenal: $perintah"
;;
esac
AKHIR
bash menu.sh mulai
bash menu.sh hentikan
bash menu.sh status
bash menu.sh ulangOutput yang Dihasilkan:
menyalakan layanan
mematikan layanan
layanan sedang berjalan
perintah tidak dikenal: ulangMari kita bedah struktur case tersebut:
case "$perintah" in: kata yang dicocokkan; pola pertama yang cocok menang, sisanya dilewati.mulai)danstop|hentikan): pola per cabang — tanda|memperbolehkan beberapa pola berbagi satu cabang, dan pola boleh memuat wildcard seperti*.;;: penanda akhir cabang, setara denganbreakdi beberapa bahasa lain.*): pola penangkap semua — cabang default untuk nilai yang tak terduga, sepertiulangpada pemanggilan terakhir.
Percabangan membuat skrip bisa memilih jalur, tetapi jalur yang sama sering perlu dijalankan berkali-kali dengan data berbeda. Pekerjaan berulang itu milik for dan while — dibahas di Chapter Loops.