Mengetik ulang perintah yang barusan saja dijalankan adalah pemborosan waktu paling klasik di terminal. Untungnya bash mencatat setiap baris yang kita jalankan dalam sebuah riwayat, dan menyediakan banyak cara memanggilnya kembali tanpa mengetik ulang. Pada Chapter ini kita akan membaca riwayat dengan history, menghapus entrinya, menjalankan ulang lewat ekspansi !! dan !awalan, mencari mundur dengan Ctrl+R, lalu mengatur panjang riwayat lewat HISTSIZE. Riwayat yang dimiliki tiap pembaca tentu berbeda-beda, jadi contoh pada buku ini membaca dari file fixture agar hasilnya bisa diverifikasi — trik yang akan kita jelaskan di sepanjang jalan.
Daftar riwayat dengan history #
Selama sesi berjalan, bash menyimpan daftar perintah di memori; saat sesi ditutup, daftar itu dituliskan ke file ~/.bash_history. Perintah history mencetak daftar tersebut lengkap dengan nomor urut. Nomor ini penting karena bisa dipakai untuk menjalankan ulang entrinya. Karena contoh buku harus memberi hasil yang sama di mana pun, blok berikut menyalin beberapa perintah ke file riwayat lalu memuatnya dengan history -r:
printf 'echo halo\nls -la\ncat catatan.txt\ngrep error app.log\n' > riwayat
history -r riwayat
historyOutput yang Dihasilkan:
1 echo halo
2 ls -la
3 cat catatan.txt
4 grep error app.logBaris pertama membuat file berisi empat perintah, satu per baris. Baris kedua, history -r riwayat, membaca file itu ke daftar riwayat sesi — pada terminal kita sendiri, pembacaan serupa terjadi otomatis dari ~/.bash_history setiap kali sesi dibuka. Baris ketiga mencetak daftarnya: nomor urut diikuti teks perintah persis seperti diketik. Di terminal rumah, angka bisa jadi melompat-lompat karena sesi baru melanjutkan penomoran dari riwayat yang tersimpan.
Menghapus entri dan membersihkan daftar #
Daftar riwayat bisa dirawat, bukan hanya dibaca. Perintah history -d nomor membuang satu entri — berguna bila kita tak sengaja menyimpan perintah berisi data sensitif — dan history -c mengosongkan seluruh daftar di memori:
printf 'echo halo\nls -la\ncat catatan.txt\ngrep error app.log\n' > riwayat
history -r riwayat
history -d 2
historyOutput yang Dihasilkan:
1 echo halo
2 cat catatan.txt
3 grep error app.logEntri nomor 2 (ls -la) lenyap dari daftar, dan entri setelahnya bergeser menempati nomornya — persis perilaku baris pada editor teks. Perintah history -c membersihkan seluruh daftar dalam sekali jalan, tetapi file ~/.bash_history di disk tidak ikut tersentuh sampai sesi menulisnya kembali. Untuk menghapus jejak secara menyeluruh, keduanya harus dibersihkan.
Menjalankan ulang dengan ekspansi !! #
Fitur tercepat dari riwayat adalah history expansion — tanda seru yang membawa perintah lama kembali ke baris saat ini. Tiga bentuknya yang paling sering dipakai:
| Bentuk | Menjalankan ulang |
|---|---|
!! | perintah terakhir (sama dengan panah atas lalu Enter) |
!cat | perintah terbaru yang berawalan cat |
!3 | perintah bernomor 3 pada daftar history |
Ekspansi ini hanya aktif di shell interaktif, sehingga tidak bisa dibuktikan dalam blok output otomatis buku ini — tetapi bentuk tampilannya kira-kira sebagai berikut, dengan !! yang mengulang cat catatan.txt beserta outputnya:
$ cat catatan.txt
isi catatan
$ !!
cat catatan.txt
isi catatan
Contoh di atas adalah contoh tampilan, bukan output terverifikasi. Perhatikan bahwa setelah !! diikuti Enter, bash lebih dulu mencetak bentuk perintah yang diperluas, baru menjalankannya — sehingga kita selalu bisa melihat apa yang sebenarnya dijalankan. Pola klasiknya adalah sudo !!: menjalankan ulang perintah terakhir dengan hak admin karena lupa menambahkan sudo di depannya.
Pencarian yang lebih luas dilayani Ctrl+R. Tekan Ctrl+R lalu ketik potongan perintah yang diingat — misalnya grep — dan bash mencari mundur dari entri terbaru sambil menampilkan kandidatnya; tekan Enter untuk menjalankan, atau panah kanan untuk menyunting dulu sebelum dijalankan. Bentuk-bentuk ekspansi lainnya terdokumentasi lengkap pada bagian HISTORY di halaman manual bash(1)
.
Stempel waktu pada riwayat #
Secara bawaan, file riwayat hanya berisi perintah, satu per baris. Bila variabel HISTTIMEFORMAT diisi, bash juga menyimpan stempel waktu dalam format baris komentar # diikuti jumlah detik sejak epoch, lalu menampilkannya di samping setiap entri:
printf '#1735689600\necho halo\n#1735689660\nls -la\n' > riwayat-waktu
history -r riwayat-waktu
HISTTIMEFORMAT='%F %T ' TZ=UTC historyOutput yang Dihasilkan:
1 2025-01-01 00:00:00 echo halo
2 2025-01-01 00:01:00 ls -laMari kita telaah baris-baris di atas:
- Baris 1 (
printf ... > riwayat-waktu): membuat file riwayat dengan dua entri ber-stempel; angka1735689600adalah detik sejak epoch, dan dua stempel itu sengaja berjarak satu menit. - Baris 2 (
history -r riwayat-waktu): memuat file tersebut ke daftar riwayat sesi. - Baris 3 (
HISTTIMEFORMAT='%F %T ' TZ=UTC history): format%F %Tmenampilkan tanggal dan waktu setiap entri;TZ=UTCmemakai zona waktu tetap supaya contoh ini menghasilkan output yang sama di komputer mana pun.
Dengan stempel waktu, riwayat berubah menjadi jejak audit sederhana: kita bisa melihat kapan sebuah perintah benar-benar dijalankan, bukan hanya apa isinya.
Mengatur ukuran riwayat #
Panjang riwayat diatur dua variabel yang biasanya dituliskan di ~/.bashrc: HISTSIZE membatasi jumlah entri yang disimpan bash di memori selama sesi, sedangkan HISTFILESIZE membatasi jumlah baris yang ditulis ke ~/.bash_history. Nilai bawaan keduanya di banyak distribusi adalah 500, dan umumnya diperbesar:
export HISTSIZE=5000
export HISTFILESIZE=10000
export HISTCONTROL=ignoredupsBaris ketiga pada contoh di atas layak dibiasakan: HISTCONTROL=ignoredups menyuruh bash tidak menyimpan perintah yang sama persis dua kali berurutan, sehingga riwayat tidak penuh oleh ls yang diketik sepuluh kali. Ketiga baris ini berlaku setelah ~/.bashrc dimuat ulang pada sesi baru.
Riwayat menghemat ketikan kita yang sudah lewat. Satu fitur produktivitas lagi menyempurnakan keduanya: pelengkapan otomatis dengan tombol Tab — materi Chapter Command Completion.