Perintah `history` di Linux: Panduan Lengkap untuk Bash History
Perintah `history` di Linux adalah utilitas bawaan shell Bash yang merekam, menampilkan, dan mengelola setiap perintah yang dieksekusi dalam sesi terminal. Perintah ini membaca dari dan menulis ke `~/.bash_history`, sebuah file teks biasa di direktori home setiap pengguna, memungkinkan Anda untuk mengingat, mencari, mengeksekusi ulang, dan mengaudit perintah lintas sesi tanpa perlu mengetiknya kembali.
Bagi administrator sistem dan pengguna tingkat lanjut, riwayat Bash bukan sekadar fitur kenyamanan — ini adalah jejak audit operasional, alat debugging, dan pengganda produktivitas. Memahami cara kerjanya secara internal, variabel konfigurasi, dan implikasi keamanannya membedakan pengguna biasa dari para insinyur yang mengekstrak nilai maksimal dari command line.
Cara Kerja Riwayat Bash Secara Internal
Ketika Anda membuka sesi terminal, Bash memuat konten `~/.bash_history` ke dalam daftar di memori. Saat Anda mengeksekusi perintah, perintah tersebut ditambahkan ke buffer dalam memori ini. Ketika sesi ditutup secara normal (melalui `exit` atau `logout`), buffer dikosongkan kembali ke `~/.bash_history` sesuai dengan aturan yang ditentukan oleh variabel lingkungan Anda.
Arsitektur ini memiliki implikasi penting: jika sesi Anda berakhir secara tidak normal (mati listrik, SSH terputus, `kill -9`), perintah dari sesi tersebut mungkin tidak pernah ditulis ke disk. Ini adalah sumber kebingungan yang umum ketika administrator kehilangan jejak perintah yang dijalankan selama sesi yang terputus.
Dua opsi shell mengubah perilaku tulis-saat-keluar default ini:
- `shopt -s histappend` — menambahkan riwayat baru ke `~/.bash_history` alih-alih menimpanya. Ini sangat penting dalam lingkungan multi-sesi.
- `PROMPT_COMMAND='history -a'` — memaksa Bash untuk menambahkan perintah terbaru ke file riwayat setelah setiap prompt, memungkinkan persistensi real-time dan visibilitas lintas terminal.
Tanpa `histappend`, shell terakhir yang ditutup yang menang — shell tersebut menimpa file riwayat, secara diam-diam membuang entri dari semua sesi bersamaan lainnya.
Penggunaan Dasar Perintah `history`
Menampilkan Riwayat Perintah Lengkap
“`bash
history
“`
Menampilkan daftar bernomor dari perintah yang tersimpan. Nomor di sebelah kiri adalah indeks riwayat, yang digunakan untuk penunjuk event.
Menampilkan Sejumlah Perintah Terbaru Tertentu
“`bash
history 20
“`
Menampilkan 20 perintah terakhir. Berguna ketika Anda perlu melihat sekilas aktivitas terbaru tanpa menggulir ratusan entri.
Menulis Riwayat Sesi Saat Ini ke File Secara Langsung
“`bash
history -w
“`
Memaksa penulisan segera dari buffer riwayat dalam memori ke `~/.bash_history`. Gunakan ini sebelum menutup sesi penting untuk memastikan tidak ada yang hilang.
Membaca Riwayat dari File ke Sesi Saat Ini
“`bash
history -r
“`
Memuat ulang `~/.bash_history` ke memori sesi saat ini. Berguna ketika Anda ingin mengakses perintah yang diketik di jendela terminal lain selama login yang sama.
Mengingat dan Mengeksekusi Ulang Perintah
Penunjuk Event dengan `!`
Sintaks penunjuk event Bash memungkinkan eksekusi ulang langsung perintah historis berdasarkan referensi:
| Penunjuk | Perilaku |
|---|---|
| — | — |
| `!!` | Menjalankan ulang perintah sebelumnya |
| `!n` | Menjalankan perintah pada indeks riwayat `n` |
| `!-n` | Menjalankan perintah `n` posisi ke belakang dari posisi saat ini |
| `!string` | Menjalankan perintah terbaru yang dimulai dengan `string` |
| `!?string?` | Menjalankan perintah terbaru yang mengandung `string` di mana saja |
| `!$` | Menggantikan argumen terakhir dari perintah sebelumnya |
| `!*` | Menggantikan semua argumen dari perintah sebelumnya |
Contoh praktis — menggunakan kembali argumen terakhir:
“`bash
mkdir /var/www/myproject
cd !$
“`
`!$` diperluas menjadi `/var/www/myproject`, menghemat Anda dari mengetik ulang path. Ini adalah salah satu fitur riwayat Bash yang paling jarang digunakan namun bernilai tinggi.
Pratinjau sebelum mengeksekusi:
Tambahkan `:p` ke penunjuk event mana pun untuk mencetak perintah tanpa menjalankannya:
“`bash
!42:p
“`
Ini adalah kebiasaan keamanan yang penting saat bekerja di server produksi. Selalu pratinjau perintah yang merusak sebelum eksekusi.
Penunjuk Kata untuk Ekstraksi Argumen
Selain menjalankan ulang seluruh perintah, Bash memungkinkan Anda mengekstrak argumen tertentu dari entri riwayat:
“`bash
!!:2 # Second word (argument) of the last command
!!:1-3 # Words 1 through 3 of the last command
!ssh:$ # Last argument of the most recent ssh command
“`
Tingkat granularitas ini sangat berharga saat membangun pipeline kompleks atau mengulang operasi pada path file yang sama.
Pintasan Keyboard untuk Navigasi Riwayat
| Pintasan | Aksi |
|---|---|
| — | — |
| `Up Arrow` / `Ctrl+P` | Pindah ke perintah sebelumnya |
| `Down Arrow` / `Ctrl+N` | Pindah ke perintah berikutnya |
| `Ctrl+R` | Pencarian balik inkremental melalui riwayat |
| `Ctrl+S` | Pencarian inkremental maju (memerlukan `stty -ixon`) |
| `Alt+.` | Menyisipkan argumen terakhir dari perintah sebelumnya |
| `Ctrl+G` | Membatalkan pencarian riwayat saat ini |
Catatan tentang `Ctrl+S`: Secara default, `Ctrl+S` memicu kontrol aliran XON/XOFF dan membekukan terminal. Untuk mengaktifkan pencarian riwayat maju, tambahkan `stty -ixon` ke `~/.bashrc` Anda.
Pencarian Balik dengan `Ctrl+R`
“`
(reverse-i-search)`git': git commit -am "fix: resolve race condition"
“`
Ketik substring dan Bash secara inkremental mencocokkan perintah terbaru yang mengandungnya. Tekan `Ctrl+R` lagi untuk berpindah ke kecocokan yang lebih lama. Tekan `Enter` untuk mengeksekusi, atau `Ctrl+G` untuk membatalkan tanpa menjalankan apa pun.
Untuk pencarian riwayat bervolume tinggi, pipe melalui `grep`:
“`bash
history | grep "docker run"
history | grep -E "^[[:space:]]+[0-9]+[[:space:]]+ssh"
“`
Mengedit dan Mengelola Entri Riwayat
Menghapus Entri Tertentu
“`bash
history -d 87
“`
Menghapus perintah pada indeks 87 dari daftar dalam memori. Untuk menjadikannya permanen, ikuti dengan `history -w` untuk menulis daftar yang dimodifikasi kembali ke disk.
Menghapus Rentang Entri
“`bash
for i in $(seq 85 90); do history -d 85; done
“`
Karena penghapusan menggeser indeks, selalu hapus nomor indeks yang sama dalam loop daripada menginkrementnya.
Menghapus Seluruh Riwayat Dalam Memori
“`bash
history -c
“`
Menghapus buffer riwayat sesi saat ini. Ini tidak menyentuh `~/.bash_history` di disk.
Menghapus Semua Riwayat Sepenuhnya
“`bash
history -c && history -w
“`
Menghapus buffer dalam memori dan kemudian menulis buffer kosong ke `~/.bash_history`, secara efektif memotong file. Ini adalah urutan dua langkah yang benar — menggunakan `> ~/.bash_history` saja tidak menghapus buffer dalam memori, sehingga file mungkin diisi ulang saat sesi berakhir.
Mengonfigurasi Riwayat Bash: Variabel Lingkungan
Semua perilaku riwayat diatur oleh variabel lingkungan, biasanya diatur di `~/.bashrc` (shell non-login interaktif) atau `~/.bash_profile` / `~/.profile` (shell login). Perubahan berlaku setelah melakukan source pada file:
“`bash
source ~/.bashrc
“`
`HISTSIZE`
Mengontrol berapa banyak perintah yang disimpan dalam memori selama sesi aktif.
“`bash
export HISTSIZE=10000
“`
Menetapkan ini ke `0` menonaktifkan riwayat dalam memori sepenuhnya. Menetapkannya ke `-1` (di Bash 4.3+) membuatnya tidak terbatas.
`HISTFILESIZE`
Mengontrol jumlah maksimum baris yang disimpan di `~/.bash_history` di disk.
“`bash
export HISTFILESIZE=20000
“`
Ketika file melebihi batas ini, Bash memangkas entri terlama. Untuk lingkungan yang sensitif terhadap kepatuhan, tetapkan ini ke nilai besar dan pasangkan dengan rotasi log.
`HISTCONTROL`
Menentukan aturan penyaringan untuk perintah mana yang direkam.
| Nilai | Perilaku |
|---|---|
| — | — |
| `ignoredups` | Melewati perintah duplikat berurutan |
| `ignorespace` | Melewati perintah yang diawali dengan spasi |
| `ignoreboth` | Menggabungkan keduanya di atas |
| `erasedups` | Menghapus semua kemunculan sebelumnya dari sebuah perintah sebelum menambahkan yang baru |
“`bash
export HISTCONTROL=ignoreboth
“`
Kasus penggunaan keamanan untuk `ignorespace`: Awali perintah apa pun yang mengandung kata sandi atau rahasia dengan spasi untuk mencegahnya direkam:
“`bash
mysql -u root -pSuperSecretPassword
“`
Ini adalah praktik keamanan operasional yang banyak digunakan pada sistem bersama atau multi-pengguna.
`HISTTIMEFORMAT`
Menambahkan timestamp ke setiap entri riwayat, disimpan sebagai baris komentar di `~/.bash_history`.
“`bash
export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "
“`
Contoh output:
“`
487 2024-11-14 09:32:17 systemctl restart nginx
488 2024-11-14 09:32:45 tail -f /var/log/nginx/error.log
“`
Timestamp sangat penting untuk forensik pasca-insiden pada lingkungan VPS Hosting dan infrastruktur dedicated. Tanpanya, Anda tahu *apa* yang dijalankan tetapi tidak *kapan*.
`HISTIGNORE`
Daftar pola glob yang dipisahkan titik dua. Perintah yang cocok dengan pola mana pun tidak disimpan ke riwayat.
“`bash
export HISTIGNORE="ls:ll:la:cd:pwd:exit:clear:history"
“`
Ini mencegah perintah-perintah sepele mengotori riwayat Anda dan mengencerkan hasil pencarian. Anda juga dapat menggunakan wildcard:
“`bash
export HISTIGNORE="*password*:*secret*:*token*"
“`
Ini adalah tindakan pertahanan berlapis — kombinasikan dengan `ignorespace` untuk kebersihan kredensial maksimal.
Tabel Referensi Lengkap Variabel Konfigurasi Riwayat Bash
| Variabel | Default | Tujuan |
|---|---|---|
| — | — | — |
| `HISTSIZE` | 500–1000 | Perintah yang disimpan dalam memori per sesi |
| `HISTFILESIZE` | 500–2000 | Baris yang disimpan di `~/.bash_history` |
| `HISTCONTROL` | (tidak diatur) | Aturan penyaringan untuk perintah yang direkam |
| `HISTTIMEFORMAT` | (tidak diatur) | Format timestamp yang ditambahkan sebelum entri |
| `HISTIGNORE` | (tidak diatur) | Pola glob untuk perintah yang dikecualikan |
| `HISTFILE` | `~/.bash_history` | Path ke file riwayat |
| `histappend` (shopt) | off | Tambah vs. timpa saat sesi berakhir |
Berbagi Riwayat di Beberapa Sesi Terminal
Secara default, setiap sesi Bash mempertahankan buffer riwayatnya sendiri yang terisolasi. Perintah yang diketik di Terminal A tidak terlihat oleh Terminal B sampai kedua sesi ditutup dan file ditulis. Bagi administrator yang mengelola beberapa sesi SSH secara bersamaan di Server Dedicated, ini menciptakan celah dalam catatan operasional.
Konfigurasi yang direkomendasikan untuk berbagi riwayat lintas sesi secara real-time:
“`bash
~/.bashrc
export HISTSIZE=100000
export HISTFILESIZE=100000
export HISTCONTROL=ignoreboth
export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "
shopt -s histappend
PROMPT_COMMAND='history -a; history -c; history -r'
“`
Yang dilakukan konfigurasi ini:
- `history -a` — menambahkan perintah terbaru ke file
- `history -c` — menghapus buffer dalam memori
- `history -r` — memuat ulang file ke memori
Setelah setiap perintah, setiap sesi terminal melihat riwayat lengkap yang terpadu dari semua sesi aktif. Pertimbangannya adalah sedikit overhead pada eksekusi `PROMPT_COMMAND`, yang dalam praktiknya dapat diabaikan.
Mencari Riwayat Secara Efisien: Teknik Lanjutan
`fzf` — Pencarian Riwayat Fuzzy
Alat `fzf` mengubah pencarian riwayat dari pemindaian linear menjadi antarmuka pencocokan fuzzy interaktif:
“`bash
Install fzf (Debian/Ubuntu)
sudo apt install fzf
Bind Ctrl+R to fzf-powered history search
Add to ~/.bashrc:
[ -f ~/.fzf.bash ] && source ~/.fzf.bash
“`
Setelah dikonfigurasi, `Ctrl+R` membuka pencarian fuzzy layar penuh atas seluruh riwayat Anda. Ini sangat powerful dengan file riwayat besar (10.000+ entri) di mana `grep` menjadi tidak praktis.
Mengekstrak Riwayat untuk Scripting
“`bash
Export all unique commands containing "iptables" to a script
history | grep iptables | awk '{$1=""; print $0}' | sort -u > iptables_audit.sh
“`
Pola ini berguna untuk merekonstruksi runbook dari perintah ad-hoc yang dieksekusi selama respons insiden.
Pertimbangan Keamanan untuk Riwayat Bash
Riwayat Bash adalah alat bermata dua. Ini mempercepat alur kerja yang sah tetapi juga merupakan permukaan serangan yang signifikan.
Risiko utama dan mitigasinya:
- Paparan kredensial: Kata sandi yang diteruskan sebagai argumen command-line (misalnya, `curl -u admin:password`) disimpan dalam plaintext di `~/.bash_history`. Gunakan `ignorespace`, `HISTIGNORE`, atau variabel lingkungan sebagai gantinya.
- Forensik eskalasi hak istimewa: Penyerang yang mendapatkan akses shell secara rutin membaca `~/.bash_history` untuk memahami lingkungan, menemukan kredensial, dan mengidentifikasi target bernilai tinggi. Tetapkan izin yang ketat: `chmod 600 ~/.bash_history`.
- Manipulasi riwayat: Pengguna yang dikompromikan dapat menjalankan `history -c && history -w` untuk menghapus semua bukti. Untuk tujuan audit pada sistem produksi, pertimbangkan pencatatan perintah berbasis `auditd` atau `syslog`, yang tidak dapat dimanipulasi oleh pengguna.
- Isolasi riwayat root: Riwayat pengguna root disimpan di `/root/.bash_history`. Pastikan file ini tidak dapat dibaca oleh semua orang dan disertakan dalam cakupan backup dan audit Anda.
Untuk lingkungan yang memerlukan audit perintah ketat — seperti infrastruktur yang mematuhi PCI-DSS atau SOC 2 — riwayat Bash saja tidak cukup. Pasangkan dengan audit tingkat kernel melalui `auditd` dan pengiriman log terpusat.
Riwayat Bash vs. Sistem Riwayat Shell Alternatif
| Fitur | Riwayat Bash | Riwayat Zsh | Riwayat Fish |
|---|---|---|---|
| — | — | — | — |
| File riwayat default | `~/.bash_history` | `~/.zsh_history` | `~/.local/share/fish/fish_history` |
| Dukungan timestamp | Melalui `HISTTIMEFORMAT` | Bawaan | Bawaan (format YAML) |
| Penanganan duplikat | `HISTCONTROL` | Opsi `HIST_IGNORE_DUPS` | Deduplikasi otomatis |
| Berbagi lintas sesi | Manual (`PROMPT_COMMAND`) | Opsi `INC_APPEND_HISTORY` | Otomatis (dibagikan secara default) |
| Antarmuka pencarian | `Ctrl+R` (linear) | `Ctrl+R` (linear) | Sorotan sintaks, sadar konteks |
| Ukuran riwayat maksimum | Variabel `HISTFILESIZE` | Variabel `SAVEHIST` | Tidak ada batas keras |
| Mekanisme penguncian | Tidak ada (kondisi race mungkin terjadi) | Penguncian file didukung | Berbasis SQLite (penulisan atomik) |
Keterbatasan utama riwayat Bash adalah kurangnya penguncian bawaan, yang dapat menyebabkan kondisi race ketika beberapa sesi menulis secara bersamaan. Zsh dan Fish menangani ini dengan lebih baik di tingkat shell.
Konfigurasi Praktis untuk Lingkungan Produksi
Berikut adalah konfigurasi riwayat `~/.bashrc` yang telah teruji untuk server Linux produksi, termasuk yang menjalankan VPS dengan cPanel atau panel kontrol kustom:
“`bash
— Bash History Configuration —
export HISTSIZE=50000
export HISTFILESIZE=50000
export HISTCONTROL=ignoreboth:erasedups
export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "
export HISTIGNORE="ls:ll:la:cd:pwd:exit:clear:bg:fg:jobs"
export HISTFILE=~/.bash_history
Append to history file; don't overwrite
shopt -s histappend
Save and reload history after each command
PROMPT_COMMAND='history -a; history -c; history -r'
Enable multi-line command history as single entry
shopt -s cmdhist
Store multi-line commands with embedded newlines
shopt -s lithist
“`
`cmdhist` dan `lithist` layak mendapat perhatian khusus. Tanpa `cmdhist`, perintah multi-baris (seperti loop `for` yang diketik secara interaktif) disimpan sebagai baris terpisah, sehingga tidak mungkin untuk dieksekusi ulang dengan bersih. Dengan `cmdhist` diaktifkan dan `lithist` diatur, seluruh konstruksi disimpan sebagai satu entri riwayat dengan newline literal, mempertahankan strukturnya.
Mengotomatiskan Alur Kerja Berbasis Riwayat
Menghasilkan Laporan Frekuensi Perintah
“`bash
history | awk '{print $2}' | sort | uniq -c | sort -rn | head -20
“`
Ini mengungkapkan 20 perintah yang paling sering Anda gunakan — berguna untuk mengidentifikasi kandidat untuk alias atau fungsi shell.
Mengaudit Penggunaan `sudo`
“`bash
history | grep sudo | awk '{$1=""; print $0}'
“`
Pada lingkungan VPS Control Panel bersama, ini memberikan audit cepat operasi yang memerlukan hak istimewa yang dilakukan selama sesi.
Merekonstruksi Timeline Sesi
“`bash
HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S " history | grep "2024-11-14"
“`
Memfilter semua perintah yang dieksekusi pada tanggal tertentu — sangat berharga selama tinjauan pasca-insiden.
Poin Teknis Utama dan Daftar Periksa Keputusan
Sebelum menerapkan konfigurasi riwayat Bash di lingkungan mana pun, validasi hal-hal berikut:
- `shopt -s histappend` diatur — mencegah kehilangan riwayat dari sesi bersamaan yang saling menimpa
- `HISTSIZE` dan `HISTFILESIZE` keduanya dikonfigurasi — mengatur hanya salah satu membiarkan yang lain pada defaultnya, menyebabkan pemotongan yang tidak terduga
- `HISTTIMEFORMAT` diaktifkan — tanpa timestamp, riwayat tidak memiliki nilai forensik
- `HISTCONTROL=ignoreboth` diatur minimal — mengurangi kebisingan dan mencegah perintah yang berdekatan dengan kredensial dari pencatatan
- `HISTIGNORE` mengecualikan perintah sepele — menjaga rasio sinyal-ke-kebisingan riwayat tetap tinggi
- `~/.bash_history` memiliki `chmod 600` — mencegah pengguna lain membaca riwayat perintah Anda
- `cmdhist` diaktifkan — memastikan perintah multi-baris disimpan sebagai unit yang koheren
- `PROMPT_COMMAND` menyinkronkan riwayat secara real-time — diperlukan untuk lingkungan multi-sesi
- `auditd` diterapkan bersamaan — untuk sistem produksi di mana pencatatan yang tahan manipulasi diperlukan
- Kredensial tidak pernah diteruskan sebagai argumen CLI — gunakan variabel lingkungan, `.netrc`, atau manajer rahasia sebagai gantinya
Pertanyaan yang Sering Diajukan
Mengapa riwayat Bash saya menghilang setelah menutup sesi SSH?
Ini biasanya terjadi karena `shopt -s histappend` tidak diatur. Tanpanya, setiap sesi menimpa `~/.bash_history` saat keluar. Jika sesi berakhir secara tidak normal (jaringan terputus, `kill -9`), penulisan tidak pernah terjadi sama sekali. Atur `histappend` dan `PROMPT_COMMAND='history -a'` untuk mempertahankan perintah secara real-time.
Bagaimana cara mencegah kata sandi disimpan dalam riwayat Bash?
Gunakan dua teknik komplementer: awali perintah dengan spasi (memerlukan `HISTCONTROL=ignorespace` atau `ignoreboth`), dan tambahkan pola perintah sensitif ke `HISTIGNORE`. Untuk kebersihan jangka panjang, jangan pernah meneruskan rahasia sebagai argumen CLI — gunakan variabel lingkungan atau alat manajemen rahasia khusus.
Apa perbedaan antara `HISTSIZE` dan `HISTFILESIZE`?
`HISTSIZE` mengontrol berapa banyak perintah yang disimpan Bash dalam memori selama sesi aktif. `HISTFILESIZE` mengontrol berapa banyak baris yang dipertahankan di `~/.bash_history` di disk. Keduanya harus diatur secara eksplisit — `HISTSIZE` yang besar dengan `HISTFILESIZE` yang kecil berarti riwayat dalam sesi Anda kaya, tetapi sebagian besar dibuang saat sesi berakhir.
Bisakah entri riwayat yang dihapus dipulihkan?
Setelah `history -c && history -w` dieksekusi, buffer dalam memori dihapus dan file dipotong — pemulihan standar tidak mungkin dilakukan. Namun, jika sistem Anda menggunakan snapshot filesystem atau solusi backup, versi sebelumnya dari `~/.bash_history` mungkin dapat dipulihkan dari snapshot. Ini adalah alasan lain untuk mengimplementasikan `auditd` untuk pencatatan yang tahan manipulasi pada infrastruktur kritis.
Bagaimana cara berbagi riwayat Bash di beberapa sesi terminal yang berjalan bersamaan?
Tambahkan yang berikut ke `~/.bashrc`: `shopt -s histappend` dan `PROMPT_COMMAND='history -a; history -c; history -r'`. Ini memaksa setiap sesi untuk menambahkan perintah terbarunya ke file bersama dan memuat ulang file lengkap setelah setiap prompt, memberikan semua terminal aktif tampilan terpadu dan real-time dari riwayat perintah.
