2010-03-31 4 views
13

Есть ли случай ... или контекст, где cat file | ... ведет себя иначе, чем ... <file?cat file | ... vs ... <файл

+0

Если вы спрашиваете, почему вы видите одну форму или другую, используемую в разных местах, это, по-видимому, вопрос личных предпочтений. Керниган и Пайк отметили это в 1984 году: http://www.amazon.com/Unix-Programming-Environment-Prentice-Hall-Software/dp/013937681X – msw

+1

Принадлежит superuser.com –

ответ

9

При чтении из обычного файла cat отвечает за чтение данных, выполняет его по своему усмотрению и может ограничить его тем, как он записывает его в конвейер. Очевидно, что содержимое сохраняется, но все остальное может быть испорчено. Например: размер блока и время поступления данных. Кроме того, труба сама по себе не всегда нейтральна: она служит в качестве дополнительного буфера между входом и ....

Быстрый и легкий способ сделать проблему размера блока кажущееся:

$ cat large-file | pv >/dev/null 
5,44GB 0:00:14 [ 393MB/s] [    <=>         ] 
$ pv <large-file >/dev/null 
5,44GB 0:00:03 [1,72GB/s] [=================================>] 100% 
+1

Интересно, хотя с учетом того, что read() использует конечный буфер, в любом случае вы ударите минимальный размер буфера для некоторых процессов. strace показывает, что кошка использует 32kB-чтения и pv 128kB на моей платформе. – msw

+0

О, эй, мой пример на самом деле не соответствует вопросу, так как я не использую <с pv. Re-running ... –

+0

@msw он будет * очень * в зависимости от реализации 'cat', но я постараюсь сделать это по-другому. –

1

cat file | запускает еще одну программу (кошку), которая не должна запускаться во втором случае. Это также делает его более запутанным, если вы хотите использовать «здесь документы». Но он должен вести себя одинаково.

4

cat позволит вам последовательно подключать несколько файлов. В противном случае < redirection и cat file | производят одинаковые побочные эффекты.

2

Трубы вызывают Подоболочка, который будет вызван для команды справа. Это мешает переменным среды.

cat foo | while read line 
do 
    ... 
done 
echo "$line" 

против

while read line 
do 
    ... 
done < foo 
echo "$line" 
+0

Оба дали те же результаты, когда я их попробовал. –

+0

интересный побочный эффект. – pra

+0

@JB: Задайте переменную внутри цикла, затем повторите ее после цикла. Измененное значение будет сохраняться только после перенаправленной формы и не будет после формы, указанной в канале. Другая демонстрация - 'cd' внутри цикла и' pwd' после цикла. –

4

Помимо вещи, размещенной других пользователями, при использовании перенаправления ввода из файла стандартного ввода является файлом, но когда конвейер от кошки к входу, стандартный ввод поток с содержимым файла. Когда стандартный ввод - это файл, можно искать в файле, но труба не разрешит его. Вы можете увидеть это, находя почтовый файл и выполнив следующие команды:

zipinfo /dev/stdin < thezipfile.zip 

и

cat thezipfile.zip | zipinfo /dev/stdin 

Первая команда покажет содержимое ZipFile в то время как второй будет показывать ошибку, хотя это является ошибочной ошибкой, потому что zipinfo не проверяет результат вызова вызова и ошибки позже.

3

A Бесполезное использование кошки всегда следует избегать. Это как движение с ручным тормозом на. Он ничего не тратит на циклы CPU, OS постоянно переключает контекст между процессом cat и следующим в трубе. Если бы все бесполезные кошки в мире исчезли и перестали быть изобретенными, изобретенными, переданными от отца к сыну, у нас не было бы глобального потепления, потому что мы могли бы легко жить с 1,21 гигаваттами энергии, спасенной.

Спасибо. Я чувствую себя лучше. Пожалуйста, присоединяйтесь ко мне в моем крестовом походе, чтобы искоренить бесполезное использование кошки в stackoverflow. Этот сайт, насколько я понимаю, является важным вкладом в распространение бесполезных кошек. Я не обвиняю новичков, но я хочу их учить. Рабочие и новички мира, ослабьте ручные тормоза и спасите планету! 1!

1

Еще одно отличие - это поведение при блокировке open() входного файла.

Например, предполагая, что вход является FIFO без каких-либо авторов, один вызов не будет порождать дочерние программы, пока входной файл не открывается, в то время как другие будут появляться два процесса:

prog ... < a_fifo  # 'prog' not launched until shell can open file 
cat a_fifo | prog ... # 'prog' and 'cat' are running (latter may block on open) 

На практике это редко кроме замысловатых обстоятельств. prog может периодически регистрировать или выполнять некоторую работу по очистке во время ожидания ввода, например, что может случиться, даже если вход отсутствует. (Почему бы не prog быть достаточно изощренным, чтобы открыть свой собственный вход fifo без блокировки?)