Perintah shell berikut diharapkan untuk mencetak hanya garis ganjil dari aliran input:
echo -e "aaa\nbbb\nccc\nddd\n" | (while true; do head -n 1; head -n 1 >/dev/null; done)
Tapi bukannya itu hanya mencetak baris pertama: aaa
.
Hal yang sama tidak terjadi ketika digunakan dengan opsi -c
( --bytes
):
echo 12345678901234567890 | (while true; do head -c 5; head -c 5 >/dev/null; done)
Perintah ini menghasilkan 1234512345
seperti yang diharapkan. Tetapi ini hanya berfungsi dalam implementasi coreutils dari head
utilitas. The busybox pelaksanaan masih makan karakter tambahan, sehingga output hanya 12345
.
Saya kira cara implementasi khusus ini dilakukan untuk tujuan optimasi. Anda tidak bisa tahu di mana garis itu berakhir, jadi Anda tidak tahu berapa banyak karakter yang perlu Anda baca. Satu-satunya cara untuk tidak mengkonsumsi karakter tambahan dari aliran input adalah dengan membaca stream byte demi byte. Tetapi membaca dari aliran satu byte pada suatu waktu mungkin lambat. Jadi saya kira head
membaca input stream ke buffer yang cukup besar dan kemudian menghitung baris di buffer itu.
Hal yang sama tidak bisa dikatakan untuk kasus ketika --bytes
opsi digunakan. Dalam hal ini Anda tahu berapa byte yang perlu Anda baca. Jadi, Anda dapat membaca persis jumlah byte ini dan tidak lebih dari itu. The corelibs implementasi menggunakan kesempatan ini, tapi busybox satu tidak, masih membaca lebih byte dari yang dibutuhkan ke dalam buffer. Mungkin dilakukan untuk menyederhanakan implementasi.
Jadi pertanyaannya. Benarkah head
utilitas mengkonsumsi lebih banyak karakter dari aliran input daripada yang diminta? Apakah ada semacam standar untuk utilitas Unix? Dan jika ada, apakah ini menentukan perilaku ini?
PS
Anda harus menekan Ctrl+C
untuk menghentikan perintah di atas. Utilitas Unix tidak gagal membaca di luar EOF
. Jika Anda tidak ingin menekan, Anda dapat menggunakan perintah yang lebih kompleks:
echo 12345678901234567890 | (while true; do head -c 5; head -c 5 | [ `wc -c` -eq 0 ] && break >/dev/null; done)
yang saya tidak gunakan untuk kesederhanaan.