Mengapa pipe "macet": buffering
- Penjelasan masalah: Saat menjalankan perintah
tail -f /some/log/file | grep thing1 | grep thing2 untuk mencari output tertentu di file log, jika baris log ditambahkan dengan lambat, output bisa tidak muncul. Ini terlihat seperti pipe macet, tetapi sebenarnya program tidak menulis data ke pipe.
Penyebab buffering
- Alasan buffering: Umumnya program melakukan buffering sebelum menulis data ke pipe atau file. Ini dilakukan untuk meningkatkan performa, dengan mengumpulkan sejumlah data lalu menulisnya sekaligus, alih-alih langsung menulis setiap output.
- Contoh:
grep thing1 menyimpan data yang cocok sampai terkumpul 8KB, sehingga output mungkin tidak segera muncul.
Tidak melakukan buffering saat menulis ke terminal
- Perbedaan terminal dan pipe:
grep menggunakan line buffering saat output diarahkan ke terminal, tetapi menggunakan block buffering saat diarahkan ke pipe. Ini ditentukan melalui fungsi isatty.
Perintah yang melakukan buffering dan yang tidak
- Perintah yang tidak melakukan buffering:
tail, cat, tee, dan lainnya tidak melakukan buffering.
- Perintah yang melakukan buffering:
grep, sed, awk, tcpdump, jq, tr, cut, dan lainnya melakukan buffering, dan sebagian dapat menonaktifkannya dengan flag tertentu.
Buffering output bawaan pada bahasa pemrograman
- Bahasa yang melakukan buffering: C, Python, Ruby, Perl, dan lainnya secara default melakukan buffering output, dan dapat dinonaktifkan dengan cara tertentu.
Kehilangan isi buffer saat menekan Ctrl-C
- Penjelasan masalah: Saat menekan
Ctrl-C, isi yang masih ada di buffer akan hilang. Ini terjadi karena sinyal SIGINT dikirim lebih dulu.
- Solusi: Cari PID
tcpdump lalu jalankan kill -TERM $PID untuk mem-flush buffer.
Buffering juga terjadi saat redirect ke file
- Redirect ke file: Saat diarahkan ke file, buffering juga tetap terjadi, tetapi masalah kehilangan buffer akibat
Ctrl-C tidak terjadi.
Beberapa cara menghindari buffering
- Solusi 1: Jalankan program yang cepat selesai.
- Solusi 2: Gunakan flag
--line-buffered pada grep.
- Solusi 3: Gunakan
awk.
- Solusi 4: Gunakan
stdbuf.
- Solusi 5: Gunakan
unbuffer.
Variabel lingkungan untuk menonaktifkan buffering
- Ide: Ada pendapat bahwa akan bagus jika tersedia variabel lingkungan standar seperti
PYTHON_UNBUFFERED. Variabel seperti NO_BUFFER diusulkan.
Isi yang dihilangkan
- Topik yang dihilangkan: Perbedaan antara line buffering dan non-buffering penuh, perbedaan buffering pada stderr dan stdout, buffering driver TTY di sistem operasi, dan sebagainya.
1 komentar
Komentar Hacker News
Akses yang dibuffer harus di-flush setelah jumlah byte atau waktu tertentu berlalu. Ini adalah cara umum untuk menyelesaikan masalah serupa pada antarmuka perangkat keras
Saat seluruh CPU sistem menjadi idle, rasanya ingin mem-flush semua buffer
Saya sudah berkutat dengan sistem NIX selama lebih dari 20 tahun, tetapi selalu lupa soal masalah buffering
Saya sudah memakai Unix selama lebih dari 35 tahun, tetapi belum pernah benar-benar memahami cara kerja buffering. Penjelasan ini bermanfaat
Ada kebingungan antara "unbuffered" dan "line buffering"
Buffer ada karena menulis ke buffer relatif jauh lebih lambat daripada mencetak output ke layar
Jika menekan Ctrl-C, isi buffer bisa hilang
Pernah mengalami masalah buffering di Unix, dan tidak semua implementasi 'awk' berperilaku sama
Saya merasa melewatkan lelucon tentang pipe yang membeku