Якщо ви хочете лише перший чи два рядки, працює наступний тип хитрощів і уникає проблем буферизації, викликаних використанням двох різних команд для читання вихідного потоку:
$ ps -eF | { IFS= read -r x ; echo "$x" ; grep worker; }
$ ls -la / | { IFS= read -r x ; echo "$x" ; grep sbin; }
readВбудований в оболонку і не споживає весь буфер введення тільки для виведення одна лінія, тому використання readзалишає все інше на виході для наступної команди.
Якщо ви хочете підкреслити проблеми буферизації, показані у ваших прикладах, які використовують дві різні команди, додайте sleepдо них, щоб усунути проблеми з тимчасовим терміном і дозволити команді зліва генерувати всі свої результати перед командами праворуч спробувати прочитати будь-яку з це:
$ ps -eF | { sleep 5 ; head -n 1 ; grep worker; }
$ ls -la / | { sleep 5 ; head -n 1 ; grep sbin; }
Тепер обидва вищевказані приклади провалюються однаково - headзчитується цілий буфер виводу просто для створення одного рядка, і цей буфер недоступний для наступних grep.
Ви можете побачити проблему буферизації ще чіткіше, використовуючи кілька прикладів, які нумерують вихідні рядки, щоб ви могли сказати, які рядки відсутні:
$ ps -eF | cat -n | { sleep 5 ; head -n 1 ; head ; }
$ ls -la /usr/bin | cat -n | { sleep 5 ; head -n 1 ; head ; }
Простий спосіб побачити проблему буферизації - це використання, seqщо генерує список чисел. Ми можемо легко визначити, які цифри пропущені:
$ seq 1 100000 | { sleep 5 ; head -n 1 ; head ; }
1
1861
1862
1863
1864
1865
1866
1867
1868
1869
Моє рішення про хитрість, що використовує оболонку для читання та повторення першого рядка, працює правильно навіть із доданим затримкою сну:
$ seq 1 100000 | { sleep 5 ; IFS= read -r x ; echo "$x" ; head ; }
1
2
3
4
5
6
7
8
9
10
11
Нижче наводиться повний приклад, що показує headпроблеми буферизації, показує, як
headвитрачається цілий буфер виводу просто для отримання його п'яти рядків кожного разу. Цей спожитий буфер недоступний для наступної
headкоманди в послідовності:
$ seq 1 100000 | { sleep 5 ; head -5 ; head -5 ; head -5 ; head -5 ; }
1
2
3
4
5
1861
1862
1863
1864
499
3500
3501
3502
3503
7
5138
5139
5140
5141
Переглядаючи число, 1861наведене вище, ми можемо обчислити розмір використовуваного буфера headшляхом підрахунку seqвиходу від 1до
1860:
$ seq 1 1860 | wc -c
8193
Ми бачимо, що headце буферизація, читаючи повний 8 КБ (8 * 1024 байт) вихідної труби за один раз, навіть для отримання лише декількох ліній власного виводу.
headІgrepнічого не робити там.