Sejauh ini kita memperlakukan terminal seperti kotak ajaib: ketik perintah, tekan Enter, hasil muncul. Di balik setiap Enter, shell melahirkan sesuatu yang hidup — sebuah process — yang diberi nomor, memakai memori, lalu mati begitu pekerjaannya selesai. Kita perlu kosakata ini sebelum bisa mengintip kegiatan sistem, menghentikan program yang macet, atau menjadwalkan tugas sendiri. Chapter ini meletakkan fondasinya, lalu menutup dengan /proc tempat kernel memajang data setiap proses.

Program Tergeletak di Disk, Proses Hidup di Memori #

Program hanyalah file — misalnya /bin/sleep — yang diam di filesystem. Proses adalah program yang sedang dijalankan: kernel memuat isinya ke memori, mencatat identitas pemiliknya, membuka file yang dibutuhkan, dan memberinya jatah waktu CPU. Satu program boleh dijalankan berkali-kali sekaligus; setiap eksekusi menghasilkan proses baru yang saling independen — kita menyebutnya sebuah instance. Data hidup proses — status, file terbuka, direktori kerja, environment — justru bisa kita baca dari /proc.

fork dan exec: Dua Langkah Lahirnya Proses #

Proses baru tidak muncul dari ketiadaan. Linux menyediakan dua system call yang bekerja berpasangan: fork() menggandakan proses yang sudah ada menjadi sepasang induk dan anak yang nyaris identik, lalu exec() mengganti isi proses anak dengan program yang baru. Ketika kita mengetik sleep 30, shell mem-fork dirinya, lalu anak hasil fork menjalankan exec() ke file /bin/sleep. Hubungan induk-anak itu bisa kita buktikan tanpa mencetak nomor PID, cukup lewat skrip kecil yang menanyakan nama induknya:

bash
printf '#!/bin/bash\nps -o comm= -p $PPID\n' > anak.sh
chmod +x anak.sh
./anak.sh
echo "induk ditemukan"

Output yang Dihasilkan:

text
bash
induk ditemukan

Mari kita bedah baris-barisnya:

  1. Baris 1-2 (printf ... > anak.sh; chmod +x): membuat skrip kecil anak.sh dan menandainya bisa dieksekusi.
  2. Baris 3 (./anak.sh): shell mem-fork dirinya, lalu anaknya menjalankan exec() ke skrip ini. Di dalam anak.sh, variabel khusus $PPID berisi PID parent, dan ps -o comm= -p $PPID mencetak hanya kolom comm — nama perintahnya.
  3. Baris 4-5 (echo ... dan hasilnya): echo menandai skrip anak selesai, lalu hasil bash membuktikan induk anak.sh adalah bash yang menjalankan blok ini — setiap proses lahir dari proses lain.

PID, PPID, dan Pohon Silsilah Proses #

Setiap proses mendapat PID (process ID): nomor bulat unik selama prosesnya hidup, sedangkan PPID (parent PID) berisi PID proses yang melahirkannya. Karena setiap proses punya tepat satu induk, seluruh proses membentuk pohon silsilah yang berakar pada proses nomor 1 — init pada sistem klasik, systemd pada distribusi modern. Bila induk mati lebih dulu, anak yang masih hidup tidak ikut mati: kernel mengadopsinya ke proses 1, dan proses seperti ini disebut orphan. Sebaliknya, proses yang sudah selesai tetapi belum dibaca exit status-nya oleh induknya sempat menjadi zombie — entri kosong yang menunggu dibaca induknya lewat wait, perintah yang akan kita praktikkan pada Chapter Foreground dan Background Processes .

Tampilan klasik untuk melihat PID dan PPID berdampingan adalah ps -f. Karena kolomnya berisi nomor PID yang berbeda pada setiap eksekusi, berikut contoh tampilannya pada satu sesi terminal, bukan output terverifikasi:

text
UID        PID  PPID  C STIME TTY          TIME CMD
budi     21001 20987  0 09:12 pts/0    00:00:00 -bash
budi     21543 21001  0 09:15 pts/0    00:00:00 sleep 30
budi     21599 21001  0 09:15 pts/0    00:00:00 ps -f

Baris pertama adalah shell tempat Budi mengetik; dua baris berikutnya anak-anaknya — PPID sleep dan ps sama persis dengan PID bash.

/proc: Direktori yang Diciptakan Saat Dibaca #

Semua data proses tadi dipajang kernel di /proc — pseudo-filesystem yang kita kenal dari Filesystem Hierarchy Standard . Setiap proses punya direktori sendiri bernama /proc/<pid>, dan pintas /proc/self selalu menunjuk ke proses yang sedang membacanya:

bash
cat /proc/self/comm
cat /proc/self/cmdline | tr '\0' '\n'

Output yang Dihasilkan:

text
cat
cat
/proc/self/cmdline

Telaah per barisnya:

  1. Baris 1 (cat /proc/self/comm): file comm berisi nama program — dan karena pembacanya adalah cat sendiri, hasilnya cat. Inilah bukti /proc/self mengikuti si pembaca.
  2. Baris 2 (cat /proc/self/cmdline | tr '\0' '\n'): file cmdline berisi seluruh argumen command line proses, dipisah karakter NUL (\0); tr menggantinya dengan baris baru sehingga kedua argumen terbaca satu per satu.

Berikut file di /proc/<pid> yang paling sering dipakai, disaring dari daftar aslinya:

bash
ls /proc/self | grep -E '^(comm|cmdline|status|stat|environ|cwd|exe)$' | sort

Output yang Dihasilkan:

text
cmdline
comm
cwd
environ
exe
stat
status

Perannya beragam: environ menyimpan variabel environment, cwd dan exe adalah symlink ke direktori kerja dan file programnya, sedangkan stat dan status merangkum keadaan proses beserta PID, PPID, dan memorinya. Dokumentasi semua field ada di halaman manual proc(5) ; standar POSIX fork menjelaskan mekanisme fork().

Kini kita memegang kosakatanya: proses punya nama, nomor, induk, dan lemari data di /proc. Pertanyaan berikutnya: bagaimana mendaftar semua proses yang hidup dan menemukan yang paling rakus CPU? Itu pekerjaan ps dan top — materi Chapter ps, top, dan htop .