Почему получение stdin из файла отличается от получения по каналу? - PullRequest
8 голосов
/ 27 января 2012

Используя bash, я часто хочу получить заголовки большого csv-файла и искать остальные записи для конкретной записи.Я делаю это следующим образом.

$ (head -1; grep mike) < tmp.csv
name,age,favourite colour
mike,38,blue

Но получение ввода от cat или любой другой команды не работает - кажется, что grep никогда не пропускает остаток файла.1006 * Почему в этих двух случаях разное поведение?

Ответы [ 3 ]

7 голосов
/ 27 января 2012

Разница между чтением из канала и чтением из файла заключается в том, что вы можете lseek для файла, но не для канала.

Поведение здесь выглядит (как видно из strace), как будто оно исходит от head, а не от bash.head прочтет буфер и найдет соответствующее количество строк, затем lseek в обратном направлении до точки, где заканчивается последняя строка вывода, оставляя дескриптор файла открытым в этом месте.Как и выше, это работает, если он читает файл, но не если он читает из канала.

Я не могу вспомнить ни одного случая другого , чем то, что вы делаете, где это поведениев head имеет смысл, но это так.Узнай что-то новое каждый день, говорю тебе ...

3 голосов
/ 27 января 2012

Очень странно.Вы не должны полагаться на это недокументированное поведение, используйте что-то вроде этого:

sed -n '1p;/mike/p' tmp.csv
0 голосов
/ 27 января 2012

Я не могу воспроизвести это надежно с помощью bash 3.2.48. Либо оба преуспевают, либо оба проваливаются. Но основной причиной сбоев является размер файла.

cat читает один буфер (4k-64k в зависимости от системы) и передает его по конвейеру. head потребляет весь буфер и затем завершается. grep затем имеет доступ к файлу после размера буфера. В моей системе я могу использовать ваш канал только для grep вещи дальше, чем один буфер в файл (поэтому я могу grep вещи в конце длинного файла, но не в начале после использования head).

Возможно, что в более поздних версиях bash оптимизируется оператор < (но не cat), чтобы ваш трюк работал, но я не думаю, что это поддерживаемое поведение.

...