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:
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:
0a1
> andi
2d2
< siti
0a1
> andi
2d2
< siti
exit code diff: 1Dua laporan diff persis sama — bukti kedua cara membaca data identik. Bedahnya baris demi baris:
- Baris 1-2: membuat dua fixture daftar yang hampir sama isinya, sengaja tidak urut.
- Baris 3-6 (cara lama): hasil
sortditumpahkan ke dua file sementara, dibacadiff, lalu dibersihkanrm -f. - Baris 7 (cara baru):
diffmenerima dua argumen “file” berisi hasilsortseketika — tanpa perantara, tanpa pembersihan. - Baris 8:
diffkeluar dengan kode1karena 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:
paste <(seq 1 3) <(seq 4 6)
cat <(printf 'senin\n') <(printf 'selasa\n')Output yang Dihasilkan:
1 4
2 5
3 6
senin
selasaDua 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:
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.txtOutput yang Dihasilkan:
ada perubahan, lihat laporan.txt
0a1
> andi
2d2
< sitiMari kita bedah isi banding.sh baris per baris:
- Baris 1 (
#!/bin/bash): shebang bash, bukansh— process substitution adalah fitur bash. - Baris 2 (
if diff <(sort ...) <(sort ...) > laporan.txt; then): dua process substitution memberidiffdaftar terurut,> laporan.txtmenangkap laporannya; exit codediffmenentukan cabangif. - 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:
| Kebutuhan | Alat yang tepat |
|---|---|
| Mengalirkan stdout ke stdin perintah lain | pipe cmd1 | cmd2 |
| Memberi output perintah sebagai argumen file | process substitution cmd <(...) |
| Data dipakai berulang kali atau ukurannya besar | file 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 .