Skrip yang hanya mencetak kalimat tetap memakai echo dari Chapter Pengenalan Terminal — tidak ada yang salah dengan itu. Namun skrip sungguhan butuh dua hal lebih: mencetak output yang terformat rapi, dan menerima data dari pengguna atau file saat berjalan. Chapter ini melengkapi echo dengan opsi-opsinya, memperkenalkan printf untuk format presisi, lalu membaca input lewat read — termasuk pola memecah baris dengan IFS yang mendasari banyak skrip pemrosesan file.

echo dan Opsi -n serta -e #

Secara bawaan echo menambahkan baris baru di setiap pencetakan. Opsi -n mematikan perilaku itu, dan -e membolehkan urutan escape seperti \t (tab) dan \n (baris baru) diterjemahkan:

bash
echo "baris biasa"
echo -n "tanpa baris baru"
echo " ... menyambung ke sini"
echo -e "kolom satu\tkolom dua"

Output yang Dihasilkan:

text
baris biasa
tanpa baris baru ... menyambung ke sini
kolom satu	kolom dua

Pada baris kedua, echo -n mencetak teks tanpa menutup baris, sehingga echo berikutnya melanjutkan di baris yang sama. Perhatikan pula bahwa echo -e memang perlu untuk menerjemahkan \t; tanpa opsi itu, teks \t tercetak apa adanya. Perilaku echo -e ini berbeda antar-shell dan antar-sistem — alasan kuat memakai printf saat format benar-benar penting.

printf: Format yang Terkontrol Penuh #

printf memisahkan dua hal yang di echo tercampur: teks tetap dan tempat nilai diletakkan. Format string memakai penanda % — %-10s berarti teks rata kiri selebar 10 karakter, %5d angka rata kanan selebar 5, dan %% mencetak tanda persen itu sendiri:

bash
printf "%-10s %5s\n" "Barang" "Harga"
printf "%-10s %5d\n" "Apel" 2500
printf "%-10s %5d\n" "Jeruk" 750
printf "diskon %.1f%%\n" 12.5

Output yang Dihasilkan:

text
Barang     Harga
Apel        2500
Jeruk        750
diskon 12.5%

Mari kita bedah penanda-penandanya:

  1. %-10s: string rata kiri dalam kolom selebar 10 karakter — nama barang yang pendek diberi spasi pengisi hingga tepat 10 kolom, membuat kolom kedua mulai di posisi yang sama di semua baris.
  2. %5d: bilangan bulat rata kanan selebar 5 — angka 750 dan 2500 sejajar di digit terakhirnya seperti daftar harga sungguhan.
  3. %.1f: bilangan pecah dengan satu angka di belakang koma; ditambah %% untuk mencetak tanda persen literal.

Berbeda dengan echo, printf tidak menambahkan baris baru — karena itu setiap format di atas ditutup \n secara eksplisit. Kombinasi lebar kolom dan rata kiri/kanan inilah yang membuat tabel keluaran skrip terbaca tanpa perintah tambahan apa pun.

Membaca Input dengan read #

Perintah read menunggu satu baris dari stdin lalu menyimpannya ke variabel. Dalam terminal interaktif, baris itu diketik pengguna; lewat pipe atau redirection, baris itu datang dari sumber lain:

bash
printf 'Budi\n' > nama.txt
cat > sapa.sh << 'AKHIR'
#!/bin/bash
read -r nama
echo "Halo, $nama!"
AKHIR
cat > sapa-p.sh << 'AKHIR'
#!/bin/bash
read -p "Nama Anda: " nama
echo "Halo, $nama!"
AKHIR
printf 'Siti\n' | bash sapa.sh
printf 'Budi\n' | bash sapa-p.sh
read -r dari_file < nama.txt
echo "dari file: $dari_file"

Output yang Dihasilkan:

text
Halo, Siti!
Halo, Budi!
dari file: Budi

Mari kita bedah blok tersebut:

  1. Baris 1-3 (printf ... > nama.txt): menyiapkan file berisi satu baris sebagai sumber data.
  2. read -r nama: opsi -r mencegah read menerjemahkan backslash — kebiasaan yang membuat input tersimpan apa adanya.
  3. printf 'Siti\n' | bash sapa.sh: pipe mengalirkan satu baris ke stdin skrip, sehingga read langsung mendapat Siti tanpa menunggu siapa pun.
  4. printf 'Budi\n' | bash sapa-p.sh: skrip kedua memakai read -p "prompt" — namun prompt tidak tercetak karena stdin bukan terminal; read -p hanya menampilkan prompt di layar ketika membaca dari terminal interaktif.
  5. read -r dari_file < nama.txt: redirection mengalihkan stdin read ke file, dan read mengambil baris pertamanya saja.

Berikut contoh tampilan sapa-p.sh saat dijalankan langsung di terminal, ketika prompt-nya benar-benar muncul:

console
budi@laptop-budi:~$ bash sapa-p.sh
Nama Anda: Budi
Halo, Budi!

Memecah Satu Baris dengan IFS #

read bisa memecah baris ke beberapa variabel sekaligus. Pemisahnya diatur variabel IFS (Internal Field Separator) yang bawaannya berisi spasi, tab, dan baris baru. Format file seperti /etc/passwd memakai titik dua sebagai pemisah, dan here-string <<< memudahkan pengujian tanpa file:

bash
baris="budi:1000:Budi Santoso:/home/budi"
IFS=: read -r user uid nama rumah <<< "$baris"
echo "user  : $user"
echo "uid   : $uid"
echo "nama  : $nama"
echo "rumah : $rumah"

Output yang Dihasilkan:

text
user  : budi
uid   : 1000
nama  : Budi Santoso
rumah : /home/budi

Penulisan IFS=: read -r ... menetapkan pemisah hanya untuk satu perintah itu — pola prefiks dari Chapter Bash Basics. Perhatikan bahwa nilai Budi Santoso mengandung spasi tetapi tetap utuh masuk ke nama, karena spasi bukan lagi pemisah ketika IFS berisi :. Pola IFS=: read ini adalah fondasi membaca file berkolom yang akan sering kita pakai di loop pada Chapter Loops.

Input dan output kini dalam genggaman kita. Satu bahan terakhir sebelum skrip bisa berpikir: percabangan logika — kondisi if dan pola case dibahas di Chapter Conditional Statements.