File log produksi bisa memuat jutaan baris, tetapi pertanyaan yang kita ajukan hampir selalu kecil: seperti apa dua puluh kejadian terakhir, atau apakah baris-baris pertama sebuah berkas konfigurasi sudah benar? Perintah head dan tail menjawab kebutuhan itu — head mengambil baris-baris awal sebuah file atau stream, sedangkan tail mengambil baris-baris akhirnya. Keduanya bekerja secara streaming: hanya bagian yang diminta yang dibaca, sehingga file sebesar apa pun selesai dalam sekejap. Pada chapter ini kita mengambil bagian awal dan akhir file, memotong mulai dari baris tertentu, menampilkan beberapa file sekaligus, lalu menutup dengan tail -f untuk memantau log.

Mengambil Baris Awal dengan head #

Tanpa opsi apa pun, head mencetak sepuluh baris pertama. Opsi -n mengubah jumlah itu, misalnya -n 5 untuk lima baris; bentuk singkat lama head -5 juga masih diterima, tetapi -n 5 lebih jelas dan lebih aman dibawa ke skrip. Kita siapkan file latihan lima belas baris bernomor:

bash
for i in $(seq 1 15); do echo "baris $i"; done > daftar.txt
head daftar.txt
head -n 5 daftar.txt
head -3 daftar.txt

Output yang Dihasilkan:

text
baris 1
baris 2
baris 3
baris 4
baris 5
baris 6
baris 7
baris 8
baris 9
baris 10
baris 1
baris 2
baris 3
baris 4
baris 5
baris 1
baris 2
baris 3

Mari kita bedah baris per barisnya:

  1. Baris 1 (for i in $(seq 1 15); do ...): membuat daftar.txt berisi lima belas baris bernomor — angkanya memudahkan kita memastikan bagian mana yang tercetak.
  2. Baris 2 (head daftar.txt): mencetak sepuluh baris pertama — jumlah bawaan head tanpa opsi -n.
  3. Baris 3 (head -n 5 daftar.txt): hanya lima baris pertama yang lolos.
  4. Baris 4 (head -3 daftar.txt): bentuk lama tanpa -n; hasilnya sama dengan head -n 3.

head juga menerima -c untuk membatasi jumlah byte, bukan baris — berguna mencomot isi file biner tanpa membanjiri terminal.

Mengambil Baris Akhir dengan tail #

tail adalah cermin head: tanpa opsi, tail mencetak sepuluh baris terakhir. Opsi -n-nya punya dua wajah. tail -n 3 mengambil tiga baris terakhir, sedangkan tail -n +12 membuang sebelas baris pertama dan mencetak mulai dari baris kedua belas sampai akhir file:

bash
for i in $(seq 1 15); do echo "baris $i"; done > daftar.txt
tail -n 3 daftar.txt
tail -n +12 daftar.txt

Output yang Dihasilkan:

text
baris 13
baris 14
baris 15
baris 12
baris 13
baris 14
baris 15

Mari kita bedah baris per barisnya:

  1. Baris 1: membuat ulang fixture lima belas baris agar blok ini bisa dijalankan sendiri.
  2. Baris 2 (tail -n 3 daftar.txt): tiga baris terakhir — baris 13 sampai baris 15.
  3. Baris 3 (tail -n +12 daftar.txt): tanda plus mengubah makna menjadi “mulai dari baris ke-12”, sehingga yang tercetak adalah baris 12 sampai baris 15 — empat baris.

Menampilkan Banyak File Sekaligus #

Bila head atau tail menerima lebih dari satu file, keluaran tiap file diberi judul ==> nama file <== agar kita tahu baris mana milik file mana:

bash
printf 'senin\nselasa\nrabu\nkamis\n' > jadwal-a.txt
printf 'jumat\nsabtu\nminggu\n' > jadwal-b.txt
head -n 2 jadwal-a.txt jadwal-b.txt
tail -n 1 jadwal-a.txt jadwal-b.txt

Output yang Dihasilkan:

text
==> jadwal-a.txt <==
senin
selasa

==> jadwal-b.txt <==
jumat
sabtu
==> jadwal-a.txt <==
kamis

==> jadwal-b.txt <==
minggu

Aturan jumlah baris tetap berlaku per file — head -n 2 mengambil dua baris pertama dari tiap file. Format berjudul seperti ini sangat membantu saat membandingkan beberapa log service sekaligus, misalnya tail -n 20 nginx.log postgres.log.

Memantau Log dengan tail -f #

tail -f (follow) tidak berhenti di akhir file: tail terus menunggu dan langsung mencetak baris baru begitu proses lain menulisnya ke file itu. Perintah ini berjalan terus sampai kita menekan Ctrl+C — pola pembuka standar admin di sesi terminal server produksi. Pemakaian klasiknya misalnya tail -f /var/log/nginx/access.log, atau beberapa log sekaligus dengan tail -f akses.log error.log. Berikut contoh tampilan tail -f yang sedang memantau log aplikasi:

console
$ tail -f aplikasi.log
10:15:02 info: koneksi diterima dari 192.0.2.10
10:15:04 info: permintaan /produk selesai dalam 12 ms
10:15:09 error: koneksi database timeout

Varian tail -F lebih tahan rotasi log: bila file diganti nama atau dibuat ulang oleh logrotate, tail -F mengikuti file barunya, sedangkan -f tetap mencengkeram file lama yang tidak lagi bertambah. Untuk analisis sesaat, pola klasiknya: ambil potongan akhir file dulu, lalu ringkas dengan peralatan section ini:

bash
printf 'info: server dimulai\nerror: database timeout\ninfo: halaman /beranda\nerror: database timeout\nerror: database timeout\n' > aplikasi.log
tail -n 4 aplikasi.log | sort | uniq -c | sort -rn

Output yang Dihasilkan:

text
      3 error: database timeout
      1 info: halaman /beranda

Mari kita bedah baris per barisnya:

  1. Baris 1: membuat file log lima baris — error: database timeout muncul tiga kali di bagian ekor.
  2. Baris 2 (tail -n 4 aplikasi.log | sort | uniq -c | sort -rn): tail -n 4 mengambil empat baris terakhir, sort mengelompokkan baris yang sama, uniq -c menghitungnya, dan sort -rn mengurutkan hasil dari yang terbanyak — pola lengkapnya sudah kita bahas di chapter sort, uniq, dan cut .

Dengan head dan tail, kita bisa mengintip ujung mana pun dari file raksasa tanpa membukanya utuh. Dua utilitas kecil di chapter berikutnya bekerja di level yang lebih halus lagi: tr mengganti karakter satu per satu, dan paste menyandingkan file berdampingan sebagai kolom. Daftar opsi lengkapnya tersedia di halaman manual head(1) dan tail(1) .