Banyak perintah Linux dirancang membaca file: diff meminta dua nama file, paste meminta beberapa daftar. Padahal data yang ingin kita olah sering kali bukan file, melainkan hasil perintah lain: keluaran sort, saringan grep, deretan angka seq. Cara konvensional: tumpuk hasil itu ke file sementara, pakai, lalu hapus — dan berharap langkah terakhir tidak terlupa. Process substitution memangkas rangkaian tersebut: bash menjalankan perintah di dalam kurung dan menyamarkan output-nya sebagai nama file semu yang bisa langsung dipakai perintah lain — tanpa satu byte pun ditulis ke disk.

File Sementara yang Berantakan #

Masalahnya: membandingkan dua file, padahal diff membaca baris demi baris sehingga kedua daftar perlu diurutkan dulu. Mengurutkan adalah pekerjaan sort — dan di sinilah benturannya: sort menulis hasilnya ke stdout, bukan ke file. Solusi klasik: tumpahkan stdout sort ke file sementara, baru diff membacanya, lalu hapus — plus risiko sampah tertinggal bila skrip berhenti di tengah jalan.

Blok berikut membandingkan kedua cara pada data yang sama:

bash
printf 'siti\nbudi\n' > daftar-lama.txt
printf 'budi\nandi\n' > daftar-baru.txt
sort daftar-lama.txt > sementara-1.txt
sort daftar-baru.txt > sementara-2.txt
diff sementara-1.txt sementara-2.txt
rm -f sementara-1.txt sementara-2.txt
diff <(sort daftar-lama.txt) <(sort daftar-baru.txt)
echo "exit code diff: $?"

Output yang Dihasilkan:

text
0a1
> andi
2d2
< siti
0a1
> andi
2d2
< siti
exit code diff: 1

Dua laporan diff persis sama — bukti kedua cara membaca data identik. Bedahnya baris demi baris:

  1. Baris 1-2: membuat dua fixture daftar yang hampir sama isinya, sengaja tidak urut.
  2. Baris 3-6 (cara lama): hasil sort ditumpahkan ke dua file sementara, dibaca diff, lalu dibersihkan rm -f.
  3. Baris 7 (cara baru): diff menerima dua argumen “file” berisi hasil sort seketika — tanpa perantara, tanpa pembersihan.
  4. Baris 8: diff keluar dengan kode 1 karena menemukan perbedaan, bukan error — perilaku yang kita kenal dari Chapter Exit Codes .

Cara Kerja <(…) dan /dev/fd #

Saat membaca <(sort daftar-lama.txt), bash menjalankan sort bersamaan dengan perintah luarnya dan menyambungkan stdout-nya ke sebuah pipe. Posisi <(...) lalu digantikan path semu seperti /dev/fd/63 — begitulah diff melihatnya sebagai nama file biasa. Direktori /dev/fd adalah jendela kernel ke file descriptor yang sedang terbuka; angkanya bervariasi antar eksekusi. Karena bentuknya argumen, process substitution boleh dipakai berkali-kali dalam satu perintah.

Menggabungkan Dua Daftar dengan paste #

Perintah paste mengambil satu baris dari setiap file lalu menggabungkannya dalam satu baris dipisah tab. Dengan process substitution, kedua “file” itu bisa berupa keluaran perintah yang berbeda sumber:

bash
paste <(seq 1 3) <(seq 4 6)
cat <(printf 'senin\n') <(printf 'selasa\n')

Output yang Dihasilkan:

text
1	4
2	5
3	6
senin
selasa

Dua seq berjalan bersamaan; paste mengambil baris pertama tiap sumber dan mencetak 1 serta 4 dalam satu baris, dan seterusnya hingga pasangan 3 dan 6. Perintah kedua menunjukkan aturan yang sama pada cat: argumen dibaca berurutan sesuai posisi.

Skrip Praktis Membandingkan Dua Daftar #

Pola ini paling bersinar di dalam skrip. banding.sh berikut membandingkan dua daftar user terurut dan menyimpan laporannya tanpa perantara:

bash
cat > banding.sh <<'AKHIR'
#!/bin/bash
if diff <(sort daftar-lama.txt) <(sort daftar-baru.txt) > laporan.txt; then
  echo "daftar identik"
else
  echo "ada perubahan, lihat laporan.txt"
fi
AKHIR
printf 'siti\nbudi\n' > daftar-lama.txt
printf 'budi\nandi\n' > daftar-baru.txt
bash banding.sh
cat laporan.txt

Output yang Dihasilkan:

text
ada perubahan, lihat laporan.txt
0a1
> andi
2d2
< siti

Mari kita bedah isi banding.sh baris per baris:

  1. Baris 1 (#!/bin/bash): shebang bash, bukan sh — process substitution adalah fitur bash.
  2. Baris 2 (if diff <(sort ...) <(sort ...) > laporan.txt; then): dua process substitution memberi diff daftar terurut, > laporan.txt menangkap laporannya; exit code diff menentukan cabang if.
  3. Baris 3-5: pesan bagi manusia sesuai hasil pemeriksaan.

Output blok membuktikan alurnya: pesan “ada perubahan” tampil, lalu cat memperlihatkan laporan.txt — andi baru dan siti hilang.

Pipe, Process Substitution, atau File Sementara #

Ketiganya berbeda wadah: pipe mengalirkan stdout ke stdin perintah berikutnya, process substitution menyalurkan output menjadi argumen file, file sementara menyimpan data di disk. Pedoman praktisnya:

KebutuhanAlat yang tepat
Mengalirkan stdout ke stdin perintah lainpipe cmd1 | cmd2
Memberi output perintah sebagai argumen fileprocess substitution cmd <(...)
Data dipakai berulang kali atau ukurannya besarfile sementara

File sementara masih tepat bila output dibaca berkali-kali, ukurannya ratusan megabyte, atau alat berikutnya menuntut file yang bisa di-seek. Untuk perbandingan dan penggabungan sehari-hari, <(...) hampir selalu lebih bersih. Rujukan lengkapnya: bagian PROCESS SUBSTITUTION di halaman manual bash(1) ; kumpulan polanya ada di Advanced Bash-Scripting Guide .

Skrip kita kini makin lincah mengolah data — tetapi satu skenario belum tertangani: apa yang terjadi bila skrip dihentikan paksa di tengah pekerjaan, justru saat file kerjanya terbuka? Jawabannya: sinyal, dan cara menangkapnya — Chapter Signals dan Traps .