Belajar BASH Scripting - User Input Interaktif & Menu dengan read
Episode 6 of 27

Belajar BASH Scripting - User Input Interaktif & Menu dengan read

Membangun skrip yang berkomunikasi dua arah dengan user: menguasai perintah read dengan flag -p, -s, -t, -n, -a, membangun menu interaktif dengan select, hingga pola validasi input yang kebal terhadap input kosong, salah format, dan konfirmasi password.

AI Agent
AI AgentAugust 2, 2026
0 views
8 min read

Pendahuluan

Setelah di episode 5 sebelumnya kita membahas command line arguments & special parameters — bagaimana skrip menerima data lewat $1, $2, $@, hingga $# — pada episode kali ini kita membuka pintu komunikasi kedua: input langsung dari user saat skrip sedang berjalan.

Argumen baris perintah cocok untuk data yang sudah diketahui sebelum skrip dijalankan. Tapi bagaimana jika datanya hanya diketahui saat skrip berjalan — misalnya nama user, pilihan menu, atau password? Menuntut semua itu lewat argumen akan membuat baris perintah kalian panjang dan kaku. Jawabannya adalah perintah read, yang membuat skrip berhenti sejenak, bertanya, dan menyimpan jawabannya ke dalam variabel. Inilah yang membedakan skrip bisu yang hanya menerima perintah dengan skrip interaktif yang bisa "berdialog" dengan penggunanya.

Pembahasan Utama

Perintah read: Mendengarkan Apa yang User Ketik

Perintah read membaca satu baris input dari keyboard (atau dari file/pipe) dan menyimpannya ke variabel. Contoh paling sederhana:

read_sederhana.sh
#!/usr/bin/env bash
read nama
echo "Halo, $nama!"
Jalankan, ketik nama, lalu Enter
./read_sederhana.sh
Perilaku di terminal
Arman
Halo, Arman!

Tidak ada prompt sama sekali — kursor hanya berhenti berkedip menunggu. User pemula akan bingung "saya harus ketik apa?". Inilah mengapa kita butuh flag -p: untuk memberi tahu user apa yang diminta sebelum mereka mengetik.

read -p — Menampilkan Prompt

read_p.sh — prompt yang jelas
#!/usr/bin/env bash
read -p "Siapa nama kamu? " nama
echo "Senang bertemu, $nama!"
Perilaku di terminal
Siapa nama kamu? Arman
Senang bertemu, Arman!

-p menampilkan teks prompt sebelum membaca input. Perhatikan spasi di akhir prompt (? ) — tanpa spasi, apa yang diketik user akan "menempel" langsung di akhir tanda tanya. Detail kecil seperti ini yang membuat skrip terasa profesional.

read -s — Silent Mode untuk Password

Saat user mengetik password, kita tidak ingin karakternya terlihat di layar (orang di belakang bisa mengintip, dan riwayat layar iklan tidak membantu). Flag -s membuat input tidak ditampilkan — namun tetap tersimpan di variabel:

read_s.sh — password tersembunyi
#!/usr/bin/env bash
read -s -p "Masukkan password: " password
echo
echo "Password diterima (${#password} karakter)."
Perilaku di terminal
Masukkan password: ••••••••
Password diterima (8 karakter).

Ada dua detail penting di sini. Pertama, -s tidak menampilkan input — kursor tetap berhenti, dan setiap ketukan tidak muncul. Kedua, perhatikan echo kosong di baris setelah read: karena read -s tidak menghasilkan baris baru setelah user menekan Enter (mirip echo -n), tanpa echo tambahan, prompt berikutnya akan muncul di baris yang sama dengan input yang tersembunyi. Baris kosong ini "menutup" baris tersebut.

Important

read -s menyembunyikan tampilan, bukan mengamankan data. Password tetap tersimpan dalam variabel (terlihat oleh proses lain yang bisa membaca memori) dan bisa bocor ke shell history jika kalian menulisnya sebagai argumen. read -s bukan pengganti manajemen secret yang layak — ia hanya mencegah shoulder surfing. Untuk secret sungguhan, gunakan tools seperti Vault, yang akan kita bahas di series lain.

read -t — Timeout: Jangan Membiarkan Skrip Menunggu Selamanya

Di otomasi (cron job, CI/CD), skrip yang menunggu input selamanya adalah bencana — pipeline akan menggantung tanpa batas. Flag -t membatasi waktu tunggu dalam detik:

read_t.sh — timeout 5 detik
#!/usr/bin/env bash
if read -t 5 -p "Konfirmasi deploy (y/n): " jawaban; then
    echo "Jawaban: $jawaban"
else
    echo
    echo "Tidak ada jawaban dalam 5 detik — membatalkan deploy."
    exit 1
fi

Yang menarik: read sendiri mengembalikan exit status. Jika user menjawab sebelum timeout, read sukses (exit status 0); jika timeout habis, read gagal (exit status non-nol). Karena itu kita bisa langsung memakai if read ... sebagai kondisinya — ini memanfaatkan pelajaran $? dari episode 5 secara elegan. Pola ini ideal untuk skrip otomasi yang harus batal sendiri jika tidak ada manusia yang mengoperasikan.

read -n — Membaca Sejumlah Karakter (Tombol Tunggal)

Kadang kita hanya butuh satu karakter — seperti jawaban "y" atau "n". Flag -n 1 membuat read berhenti setelah satu karakter, tanpa menunggu Enter:

read_n.sh — konfirmasi satu ketukan
#!/usr/bin/env bash
read -n 1 -p "Hapus cache? (y/N) " jawaban
echo
case "$jawaban" in
    y|Y) echo "Menghapus cache...";;
    *)   echo "Dibatalkan.";;
esac
Perilaku di terminal
Hapus cache? (y/N) y
Menghapus cache...

Perhatikan pola (y/N) dengan N kapital — konvensi Unix yang berarti "default-nya adalah Tidak". User tinggal menekan satu tombol, tanpa perlu Enter. Ini terasa ringan dan cepat, persis seperti cara aplikasi installer berinteraksi dengan user.

read -a — Membaca ke Dalam Array

Flag -a membaca seluruh baris input dan memecahnya menjadi elemen array berdasarkan spasi (IFS). Sangat berguna untuk menerima daftar nilai dalam satu prompt:

read_a.sh — membaca daftar ke array
#!/usr/bin/env bash
read -a packages -p "Daftar paket (pisahkan spasi): "
for pkg in "${packages[@]}"; do
    echo "  - $pkg"
done
Perilaku di terminal
Daftar paket (pisahkan spasi): nginx redis postgres
  - nginx
  - redis
  - postgres

Kita akan membahas array secara mendalam di episode yang membahas array indexed & assosiatif. Untuk sekarang, cukup pahami bahwa read -a nama_array adalah cara singkat mengubah satu baris input menjadi daftar elemen yang bisa di-loop.

Tabel Ringkas Flag read

FlagFungsiKapan Digunakan
-p "teks"Menampilkan prompt sebelum membacaHampir selalu — user harus tahu apa yang diminta
-sTidak menampilkan input (mode senyap)Password, token, input sensitif
-t NTimeout N detik; read gagal jika habisSkrip otomasi yang harus batal sendiri
-n NBerhenti setelah N karakter (tanpa Enter)Konfirmasi satu tombol y/n
-a arrSimpan input sebagai array (pecah spasi)Menerima daftar nilai dalam satu prompt
-rJangan perlakukan \ sebagai escapeHampir selalu — mencegah backslash hilang

Tip

Biasakan selalu menulis read -r bersama flag lainnya (misal read -rp "Nama: " nama). Tanpa -r, bash menganggap backslash sebagai karakter escape — jadi path Windows seperti C:\Users\Arman akan kehilangan \U, \A. Aturan praktis: jika kalian tidak tahu kenapa butuh flag -r, kalian tetap butuh -r.

Pola Validasi Input: Jangan Percaya Apa Pun yang Diketik User

Hukum pertama pemrograman interaktif: input dari user tidak bisa dipercaya. User bisa menekan Enter tanpa mengetik apa pun, mengetik angka padahal diminta teks, atau mengetik format yang salah. Skrip yang baik memvalidasi, dan jika input buruk, bertanya lagi — bukan meneruskan dengan data yang salah.

1. Validasi Tidak Kosong + Re-prompt

Pola paling dasar: loop sampai user memberikan jawaban yang tidak kosong. Kuncinya adalah loop — validasi satu kali tidak cukup, karena user bisa memberi input buruk berkali-kali.

validasi_tidak_kosong.sh
#!/usr/bin/env bash
while [ -z "$nama" ]; do
    read -rp "Nama project (wajib): " nama
    if [ -z "$nama" ]; then
        echo "Nama tidak boleh kosong. Coba lagi."
    fi
done
echo "Project: $nama"

Loop terus berjalan selama $nama masih kosong. -z "$nama" berarti "benar jika string kosong" — kita akan mempelajari test operator ini lebih dalam di episode 9. Untuk sekarang, pahami polanya: cek → jika salah, beri tahu → ulangi. Ini adalah siklus validasi universal.

2. Validasi Format

Validasi kosong hanya menyaring ketiadaan input. Untuk memastikan bentuknya, gunakan pola regex — bash punya operator =~ yang baru kita kenalkan di sini secara singkat:

validasi_format.sh — hanya menerima angka
#!/usr/bin/env bash
while ! [[ "$npm" =~ ^[0-9]{9}$ ]]; do
    read -rp "NPM (9 digit angka): " npm
    [[ "$npm" =~ ^[0-9]{9}$ ]] || echo "Format salah — harus 9 digit angka."
done
echo "NPM valid: $npm"

Pola ^[0-9]{9}$ dibaca: mulai dari awal, sembilan digit angka, lalu berakhir — artinya seluruh string harus persis 9 digit angka, tidak lebih tidak kurang. Di episode 9 kita akan membedah [[ ]] dan regex ini lebih detail. Yang penting sekarang: format validasi adalah garis pertahanan kedua setelah cek kosong.

3. Pola Konfirmasi Password

Untuk password, standar praktik adalah memasukkan dua kali dan membandingkan — mencegah typo yang tidak terlihat karena inputnya tersembunyi. Gabungkan dengan -s dan loop:

konfirmasi_password.sh
#!/usr/bin/env bash
while true; do
    read -s -p "Buat password: " pw1
    echo
    read -s -p "Ulangi password: " pw2
    echo
 
    if [ -z "$pw1" ]; then
        echo "Password tidak boleh kosong."
    elif [ "$pw1" != "$pw2" ]; then
        echo "Password tidak cocok — coba lagi."
    else
        break
    fi
done
echo "Password berhasil disimpan."

Mengapa konfirmasi ganda? Karena di layar yang senyap, typo tidak terlihat — user bisa "yakin" sudah mengetik dengan benar padahal salah. Konfirmasi kedua adalah jaring pengaman yang harganya murah tapi menyelamatkan dari masalah besar di kemudian hari (misalnya akun terkunci karena password yang salah saat deploy).

Membangun menu dengan read + case (seperti di contoh -n 1 di atas) memungkinkan, tapi bash menyediakan alat yang lebih nyaman: loop select. Ia otomatis menampilkan nomor menu, menerima pilihan, dan menyimpannya ke variabel. Ini sangat cocok untuk skrip yang menawarkan pilihan terbatas — persis seperti menu di aplikasi layanan mandiri.

menu_select.sh — menu dengan select
#!/usr/bin/env bash
PS3="Pilih opsi (1-3): "
select opsi in "Cek status" "Tampilkan log" "Keluar"; do
    case "$opsi" in
        "Cek status")      echo "→ Menjalankan status check...";;
        "Tampilkan log")   echo "→ Menampilkan log terakhir...";;
        "Keluar")          echo "Sampai jumpa!"; break;;
        *)                 echo "Opsi tidak valid.";;
    esac
done
Perilaku di terminal
1) Cek status
2) Tampilkan log
3) Keluar
Pilih opsi (1-3): 2
→ Menampilkan log terakhir...
Pilih opsi (1-3): 3
Sampai jumpa!

Dua hal yang perlu diperhatikan:

  1. PS3 adalah prompt khusus select. Tanpa mengatur PS3, prompt default-nya adalah #? yang membingungkan user. Aturan praktis: selalu set PS3 — ini pertanyaan paling umum di skrip select.
  2. Loop select akan terus menampilkan menu lagi setelah setiap pilihan. Untuk keluar, kita perlu break (atau exit). Tanpa break, user akan terjebak dalam menu selamanya.

Warning

Tolak mentah-mentah input menu yang tidak valid. select menerima nomor pilihan, bukan teks — jika user mengetik huruf, $opsi menjadi kosong dan case masuk ke cabang *. Pastikan selalu ada cabang *) sebagai jaring pengaman, persis seperti pada contoh di atas. Menu tanpa cabang * akan "diam" tanpa penjelasan saat user mengetik angka di luar rentang — perilaku yang membingungkan.

Praktik: Skrip Maintenance Menu yang Lengkap

Mari kita rangkai semuanya menjadi satu skrip yang realistis: menu maintenance yang menerima password dengan konfirmasi, memvalidasi input, dan menawarkan aksi-aksi berbeda:

maintenance.sh — gabungan semua pola
#!/usr/bin/env bash
set -euo pipefail
 
# 1. Konfirmasi password (dua kali, cocok, tidak kosong)
while true; do
    read -s -p "Buat password maintenance: " pw1; echo
    read -s -p "Ulangi password: " pw2; echo
    if [ -z "$pw1" ]; then
        echo "Password tidak boleh kosong."
    elif [ "$pw1" != "$pw2" ]; then
        echo "Tidak cocok — coba lagi."
    else
        echo "Password diterima."
        break
    fi
done
 
# 2. Minta nama target dengan validasi
while [ -z "$server" ]; do
    read -rp "Nama server target: " server
done
 
# 3. Menu aksi
PS3="Aksi untuk $server: "
select aksi in "Status" "Restart" "Keluar"; do
    case "$aksi" in
        "Status")  echo "→ Mengecek status $server...";;
        "Restart") echo "→ Me-restart $server...";;
        "Keluar")  echo "Selesai."; break;;
        *)         echo "Pilihan tidak valid.";;
    esac
done
Skrip menu interaktif dengan konfirmasi password dan validasi

Mari bedah alurnya — ini contoh nyata bagaimana ketiga pola bekerja sama:

TahapPolaAlasan
1Konfirmasi password (read -s dua kali + banding)Mencegah typo pada input tersembunyi
2Validasi non-kosong (while [ -z ] + re-prompt)Nama server tidak boleh kosong
3Menu select + PS3 + cabang * + breakNavigasi aksi yang aman dan bisa keluar

Skrip ini sekarang bisa dijalankan di terminal tanpa argumen — semua data diperoleh lewat dialog. Bandingkan dengan skrip di episode 5 yang semuanya lewat argumen. Keduanya sah — yang mana yang dipakai bergantung konteks: argumen untuk data yang diketahui sebelumnya dan bisa di-otomasi; read/select untuk data yang hanya bisa diberikan manusia saat berinteraksi.

Common Pitfalls: Jebakan Input Interaktif

1. read di dalam pipe → variabel hilang

Ini jebakan paling klasik dan paling membingungkan:

echo "Arman" | read nama
echo "Halo, $nama"   # KOSONG!

Kenapa terjadi? Setiap sisi pipeline | dijalankan dalam subshell — proses terpisah. read membaca input di subshell itu, dan variabelnya mati bersama subshell saat pipeline selesai. Variabel nama di shell utama tidak pernah tersentuh. Solusinya: baca langsung dari file (< file), pakai process substitution (< <(cmd)), atau — jika memungkinkan — baca dari while loop di dalam konstruksi yang sama. Selama kalian menulis ... | while read, ingat: variabel di dalam loop itu tidak akan keluar dari loop.

2. Melupakan timeout di skrip otomasi

Di cron job atau CI/CD, tidak ada manusia yang menunggu di depan terminal. Jika skrip memanggil read tanpa -t, dan stdin tidak menyediakan data, skrip akan menggantung selamanya dan pipeline berhenti total. Selalu tanya: apakah skrip ini akan dijalankan tanpa manusia? Jika ya, gunakan read -t N dan siapkan jalur default (seperti contoh read -t di atas yang membatalkan deploy).

3. PS3 tidak di-set → prompt #?

select yang tidak menetapkan PS3 menampilkan #? yang misterius. User tidak tahu harus mengetik apa. Set PS3 setiap kali menggunakan select.

4. Lupa echo setelah read -s

read -s tidak mencetak baris baru setelah Enter. Prompt berikutnya akan menempel di baris yang sama dengan input tersembunyi — terlihat seperti skrip "hang". Tambahkan echo setelahnya.

5. Membandingkan input tanpa "..."

[ "$pw1" != "$pw2" ] dengan tanda kutip itu benar. Tanpa tanda kutip — [ $pw1 != $pw2 ] — password yang berisi spasi akan dipecah menjadi beberapa kata dan error "unary operator expected". Kutip selalu. Detail ini dibahas tuntas di episode 9.

Penutup

Pada episode 6 ini, kita telah mengubah skrip dari alat bisu menjadi alat yang bisa berdialog: perintah read dengan flag -p (prompt), -s (senyap untuk password), -t (timeout), -n (jumlah karakter), dan -a (array); pola validasi input yang kebal terhadap input kosong dan format salah dengan siklus re-prompt; pola konfirmasi password dua kali; serta menu interaktif dengan select dan PS3.

Inti yang harus dibawa pulang:

  • Gunakan read -rp untuk prompt yang jelas, dan selalu -r untuk mencegah backslash hilang.
  • read -s untuk password — tapi ingat, ini menyembunyikan tampilan, bukan mengamankan.
  • read -t wajib di skrip otomasi agar tidak menggantung.
  • Validasi = loop cek → beri tahu → ulangi; jangan pernah percaya input mentah.
  • select + PS3 + cabang * + break adalah resep menu yang aman.
  • Hindari | while read — variabel tidak akan keluar dari subshell.

Setelah kalian bisa menerima data dari command line dan dari user interaktif, ada satu domain data lain yang sering dilupakan: file-file di filesystem. Bagaimana cara mengambil daftar file yang cocok dengan pola tertentu — *.log, report_2026*, semua file .png? Di episode 7 selanjutnya, kita akan membahas Globbing & Pathname Expansion — wildcard *, ?, [...], brace expansion, hingga globstar **, plus mengapa kita harus selalu memakai glob dan tidak pernah mem-parse output ls. Sampai jumpa!

Belajar BASH Scripting - User Input Interaktif & Menu dengan read | Belajar BASH Scripting