Когда я передаю несколько unix-команд, таких как grep, sed, tr и т. Д., Я склонен указывать входной файл, который обрабатывается с помощью cat. Так что-то вроде cat file | grep ... | awk ... | sed ...
.
Но недавно после того, как на мои ответы остались несколько комментариев о том, что это бесполезное использование кошки, я решил задать этот вопрос здесь.
Я посмотрел на проблему и наткнулся на статью Википедии о UUOC и награде «Бесполезное использование кошек», и мне кажется, что приведенные аргументы с точки зрения эффективности.
Ближайший вопрос, с которым я здесь столкнулся, был такой: расточительно называть кота? - но это не совсем то, что я спрашиваю.
Я предполагаю, что лагерь UUOC предлагает использовать cmd1 args < file | cmd2 args | cmd3 ..
или если команда имеет опцию для чтения из файла, а затем для передачи файла в качестве аргумента.
Но мне cat file | cmd1 ... | cmd2
кажется, что намного легче читать и понимать. Мне не нужно запоминать разные способы отправки входных файлов для разных команд, и процесс логически протекает слева направо. Сначала ввод, потом первый процесс ... и так далее.
Я не понимаю, какие аргументы приводятся в отношении бесполезного использования кошки? Я понимаю, что если я запускаю задание cron, которое запускается каждые 2 секунды и выполняет много операций, то в этом случае cat может быть расточительным. Но в противном случае, каково общее согласие относительно использования кошки?
источник
< file cmd1 args | cmd2 args ...
тоже работает ... так что ваш аргумент " слева направо " является недействительным. Я часто использую это для ясности - порядок, который я показал, может заставить людей остановиться, что нехорошо. С увеличением числа потоков становится нормой, это становится все менее проблемным IMO ...Ответы:
Это бесполезно в том смысле, что его использование не приводит ни к чему другому, возможно, более эффективные варианты не могут (т.е. дают правильные результаты).
Но
cat
гораздо мощнее, чем простоcat somefile
. Посоветуйтесьman cat
или прочитайте, что я написал в этом ответе . Но если вам абсолютно положительно нужно только содержимое одного файла, вы можете получить некоторое преимущество в производительности, если не будете использоватьcat
содержимое файла.Что касается читабельности, это зависит от ваших личных вкусов. Мне нравится
cat
вставлять файлы в другие команды по той же причине, особенно если аспекты производительности незначительны.Это также зависит от того, что вы пишете. Если это ваша собственная оболочка и удобные методы для вашего настольного компьютера, никто, кроме вас, не будет заботиться. Если вы наткнетесь на случай, когда следующему инструменту в цепочке будет лучше искать его, и распространите его как часто используемую часть программного обеспечения в какой-то минимальной системе Linux на низкопроизводительном маршрутизаторе или аналогичном устройстве с реальными ограничениями на способность обработки, это другое. Это всегда зависит от контекста.
источник
В каждодневном использовании командной строки это не сильно отличается. Особенно вы не заметите никакой разницы в скорости, поскольку время на ЦП, которое не используется
cat
, ваш ЦП просто простаивает. Даже если вы просматриваете сотни или тысячи (или даже сотни тысяч) элементов во всей практичности, это не будет иметь большого значения, если вы не находитесь в очень загруженной системе (Load Average / N CPU> 1).То, где резина встречается с дорогой, - это формирование хороших привычек и предотвращение плохих. Чтобы вытянуть заплесневелое клише, дьявол кроется в деталях. И именно такие детали отделяют посредственного от великого.
Это как во время вождения автомобиля, зачем делать левый поворот, если вместо этого можно сделать три правых? Конечно можно, и это отлично работает. Но если вы понимаете силу левых поворотов, то три человека кажутся просто глупыми.
Речь идет не о сохранении одного дескриптора файла, 17 КБ ОЗУ и 0,004 секунды процессорного времени. Речь идет о всей философии использования UNIX. «Сила левого поворота» на моей иллюстрации - это не просто перенаправление ввода, это философия UNIX. Полное уклонение от этого сделает вас намного лучше, чем окружающие, и вы заслужите уважение тех, кто понимает.
источник
cat
не устранит пагинацию, хотя трубопроводы на что - то может устранить пейджинг некоторых приложений.Я часто использую
cat file | myprogram
в примерах. Иногда меня обвиняют в бесполезном использовании кошки ( http://www.iki.fi/era/unix/award.html ). Я не согласен по следующим причинам:Легко понять, что происходит.
При чтении команды UNIX вы ожидаете команду, за которой следуют аргументы и перенаправление. Это есть возможность поставить перенаправление где - нибудь , но это редко - таким образом , у людей будет больше времени на чтение пример. Полагаю
легче читать, чем
Если вы переместите перенаправление в начало, вы вводите в заблуждение людей, которые не привыкли к этому синтаксису:
и примеры должны быть легкими для понимания.
Это легко изменить.
Если вы знаете, что программа может читать из cat, вы обычно можете считать, что она может читать выходные данные любой программы, которая выводит данные в STDOUT, и, таким образом, вы можете адаптировать ее для своих собственных нужд и получать предсказуемые результаты.
Подчеркивается, что программа не даст сбой, если STDIN не является обычным файлом.
Не безопасно предполагать, что, если
program1 < foo
работает, тоcat foo | program1
также будет работать. Тем не менее, это на практике можно предположить обратное. Эта программа работает, если STDIN является файлом, но завершается неудачей, если вход является каналом, потому что она использует поиск:Я посмотрел на снижение производительности на http://oletange.blogspot.dk/2013/10/useless-use-of-cat.html Вывод не использовать,
cat file |
если сложность обработки похожа на простой grep и производительность важнее, чем удобочитаемость. Для других ситуацийcat file |
это хорошо.источник
Я думаю, что позиция некоторых из тех, кто комментирует что-то, что является UUOC, заключается в том, что если человек действительно понимает синтаксис Unix и оболочки, он не будет использовать cat в этом контексте. Это похоже на использование плохой грамматики: я могу написать предложение, используя плохую грамматику, и все же донести свою мысль, но я также демонстрирую свое плохое понимание языка и, соответственно, мое плохое образование. Поэтому говорить, что что-то является UUOC, - это еще один способ сказать, что кто-то не понимает, что он делает.
Что касается эффективности, то если вы выполняете конвейер из командной строки, машине требуется меньше времени для выполнения,
cat somefile |
чем вам, чтобы подумать о том, может ли она быть более эффективной в использовании< somefile
. Это просто не имеет значения.источник
cat somefile | prog
в shell без cat, например,prog < somefile
но они всегда казались мне в неправильном порядке, особенно с помощью цепочки команд, соединенных вместе. Теперь я вижу это так же элегантно, как< somefile prog
и трюк, спасибо. Я исчерпал оправдания, которые я оставил, чтобы использовать кошку.Я не знал о награде до сегодняшнего дня, когда какой-то новичок попытался наколоть UUOC на меня для одного из моих ответов. Это было
cat file.txt | grep foo | cut ... | cut ...
. Я дал ему часть своего разума, и только после этого посетил ссылку, которую он дал мне, ссылаясь на происхождение награды и практику этого. Дальнейшие поиски привели меня к этому вопросу. К сожалению, несмотря на сознательное рассмотрение, ни один из ответов не содержал моего обоснования.Я не хотел защищаться, обучая его. В конце концов, в мои молодые годы я написал бы команду так,
grep foo file.txt | cut ... | cut ...
потому что всякий раз, когда вы выполняете частые одиночныеgrep
операции, вы изучаете расположение аргумента файла, и вы уже знаете, что первым является шаблон, а последующими - имена файлов.Это был осознанный выбор, когда я ответил на вопрос с
cat
префиксом частично из-за причины «хорошего вкуса» (по словам Линуса Торвальдса), но главным образом из-за неотразимой причины работы.Последняя причина более важна, поэтому я изложу ее в первую очередь. Когда я предлагаю трубопровод в качестве решения, я ожидаю, что его можно будет использовать повторно. Вполне вероятно, что конвейер будет добавлен в конце или объединен в другой конвейер. В этом случае файл , имеющий аргумент Grep щурит многократное использование, и вполне возможно , сделать это тихо и без сообщения об ошибке , если файл существует аргумент. И. е.
grep foo xyz | grep bar xyz | wc
даст вам , сколько строк вxyz
содержат вbar
то время как вы ожидаете , количество строк , которые содержат какfoo
иbar
. Необходимость изменить аргументы команды в конвейере перед ее использованием подвержена ошибкам. Добавьте к этому возможность молчаливых неудач, и это станет особенно коварной практикой.Не менее важна и первая причина, так как много «хорошего вкуса» просто является интуитивным подсознательным обоснованием таких вещей, как молчаливые неудачи, описанные выше, о которых вы не можете вспомнить в тот момент, когда кто-то, нуждающийся в образовании, говорит «но это не так». этот кот бесполезен ".
Тем не менее, я постараюсь также осознать прежнюю причину «хорошего вкуса», которую я упомянул. Эта причина связана с духом ортогонального дизайна Unix.
grep
не делаетcut
иls
не делаетgrep
. Поэтому, по крайней мере,grep foo file1 file2 file3
идет вразрез с духом дизайна. Ортогональный способ сделать этоcat file1 file2 file3 | grep foo
. Теперь,grep foo file1
это просто особый случайgrep foo file1 file2 file3
, и если вы не относитесь к нему одинаково, вы, по крайней мере, используете мозговые циклы, пытаясь избежать бесполезного награждения кошек.Это приводит нас к аргументу, который
grep foo file1 file2 file3
объединяет иcat
объединяет, так что это уместно,cat file1 file2 file3
но потому, чтоcat
мы не объединяемся,cat file1 | grep foo
поэтому мы нарушаем дух какcat
всемогущего, так и всемогущего Unix. Что ж, если бы это было так, тогда Unix потребовалась бы другая команда, чтобы прочитать вывод одного файла и выложить его на стандартный вывод (не разбивать его на страницы или что-то еще, просто наплевать на стандартный вывод). Таким образом, у вас возникнет ситуация, когда вы говоритеcat file1 file2
или говоритеdog file1
и добросовестно помните, чтобы избежать того,cat file1
чтобы избежать получения награды, и при этом избегать,dog file1 file2
так как, надеюсь, дизайнdog
выдаст ошибку, если будет указано несколько файлов.Надеемся, что в этот момент вы сочувствуете разработчикам Unix за то, что вы не включили отдельную команду для разбрызгивания файла на стандартный вывод, а также назвали
cat
конкатенацию вместо того, чтобы давать ей другое имя.<edit>
есть такая собака, несчастный<
оператор. К сожалению, его размещение в конце трубопровода препятствует легкому составлению. Не существует синтаксически или эстетически чистого способа разместить его в начале. К сожалению, недостаточно универсален, поэтому вы начинаете с собаки, а просто добавляете другое имя файла, если хотите, чтобы оно обрабатывалось после предыдущего. (С>
другой стороны, он не в два раза хуже. У него почти идеальное расположение в конце. Обычно он не является частью многоразового использования конвейера, и, соответственно, он символически выделяется.)</edit>
Следующий вопрос: почему важно иметь команды, которые просто плюют файл или объединяют несколько файлов в стандартный вывод без какой-либо дальнейшей обработки? Одна из причин - избегать использования каждой отдельной команды Unix, работающей со стандартным вводом, чтобы знать, как анализировать хотя бы один аргумент файла командной строки и использовать его в качестве ввода, если он существует. Вторая причина заключается в том, чтобы пользователям не приходилось запоминать: (а) куда идут аргументы имени файла; и (b) избежать ошибки тихого конвейера, как упомянуто выше.
Это подводит нас к тому, почему
grep
есть дополнительная логика. Логическое обоснование состоит в том, чтобы обеспечить свободное владение пользователями для команд, которые используются часто и автономно (а не как конвейер). Это небольшой компромисс ортогональности для значительного увеличения удобства использования. Не все команды должны быть разработаны таким образом, и команды, которые не часто используются, должны полностью избегать дополнительной логики аргументов файла (помните, что дополнительная логика приводит к ненужной хрупкости (возможность ошибки)). Исключением является разрешение файловых аргументов, как в случаеgrep
. (кстати, обратите внимание, что уls
него совершенно другая причина не просто принимать, а в значительной степени требовать аргументы файла)Наконец, то, что можно было бы сделать лучше, - это если такие исключительные команды, как
grep
(но не обязательноls
), генерируют ошибку, если доступен стандартный ввод. Это разумно, потому что команды включают логику, которая нарушает ортогональный дух всемогущего Unix для удобства пользователя. Для дальнейшего удобства пользователя, т.е. для предотвращения страданий, вызванных молчаливым отказом, такие команды не должны стесняться нарушать собственное нарушение, предупреждая пользователя, если существует возможность молчаливого отказа.источник
grep pattern f1 f2 f3
это не простая конкатенация .grep
знает о файлах и печатает имена файлов (и, необязательно, номера строк и все остальное).grep . /sys/kernel/mm/transparent_hugepage/*
хороший способ печати имени файла: file-content с множеством однострочных файлов. Классический дизайн Unix заключается в том, что большинство утилит работают*.txt
без необходимостиcat
.cat
предназначен для объединения нескольких файлов в один поток.grep
пример такой программойcut
, у которой нет причин заботиться о нескольких файлах, и она всегда может быть запитана с его стандартного ввода. Некоторые утилиты, напримерtr
, вообще не принимают файловые аргументы, а работают только как фильтры, поэтому выбор междуcat
и<
.<file cmd1 | cmd2 >out
Признаюсь, это не замечательно, но к этому вполне можно привыкнуть. Вы продолжаете рассуждать о «духе всемогущего Unix» насмешливо, что для меня совершенно неуместно, потому что звучит так, будто вы либо не понимаете, либо не хотите понять, как на самом деле думали дизайнеры Unix. Хорошо, если вам не нравится дизайн Unix, но он не глуп по своей сути. Я не уверен, предшествовал ли дизайн ОС синтаксису оболочки и как все это развивалось, ноcat
в 1970-м стоило избежать лишнего !cat
помогает повторно использовать и соединять конвейеры, тогда как без него вы можете получить тихие сбои (ищите «тихо» в моем ответе).В защиту бесполезного использования кота
(Несколько абзацев, чтобы помочь сбалансировать цунами ворчащих комментариев против этой практики)
Я слишком много лет использую bash как оболочку, так и в качестве языка сценариев для небольших сценариев (а иногда, к сожалению, для не очень маленьких). Давным-давно я узнал о «бесполезном использовании кошки» (UUoC). Я по-прежнему виновен в этом, по крайней мере, каждую неделю, но, честно говоря, я редко чувствую себя вынужденным избегать этого. Я считаю, что использование
cat
vs< file
- это скорее вкус, чем технические различия, и я написал этот ответ, чтобы защитить людей, плохо знакомых с Linux, которые разделяют мой вкус кcat
от мысли, что в их пути что-то серьезно не так (и обратите внимание на несколько случаев, когда это происходит). Как и Линус Торвальдс, я также считаю, что зачастую вкус важнее, чем умение. Это не значит, что мой вкус лучше, чем у вас, но это значит, что если что-то имеет плохой вкус, я не сделаю это, не приобретя чего-то достойного.Уже очевидно, что, как и автор вопроса, я чувствую, что использование cat очень естественно при работе над REPL, например, bash, где я исследую проблему, постепенно наращивая сложные команды. Вот очень типичный пример: у меня есть текстовый файл, и я не знаю о нем много. Я буду печатать,
cat file
чтобы получить вкус содержимого. Если выход слишком много я ударил стрелок вверх и в зависимости от обстоятельств , я добавлю| head
или| grep foo
или| what_ever
расширяя свою предыдущую команду, добавив обработку шагов. Этот способ постепенного перехода от простой команды к более сложной путем добавления одного шага обработки за другим мне кажется очень естественным (я делаю то же самое на ipython и мне нравится способpyfunctional
и подобные инструменты программирования охватывают этот стиль). Так что, работая над оболочкой bash, я уверен, что прерывание моего потока для удаленияcat
является более бесполезным, чем позволить ему быть и страдать ... ну, в 99,9% случаев это не имеет никакого значения.Конечно, при написании сценариев все может измениться. Но даже когда я пишу сценарии, я считаю, что люди, которые насмехаются над UUoC, игнорируют важные уроки: «Преждевременная оптимизация - корень всего зла» . И если вы не делаете что-то нетипичное, для UUoC действительно трудно быть местом, где потребуется оптимизация. Конечно, вам определенно нужно знать, что в этом неэффективно (это, кстати, дополнительный вызов процесса, поскольку об этом, похоже, мало кто упоминает). Обладая этими знаниями, если вам доведется работать в тех редких системах, где вызов процесса стоит дорого (например, некоторые встроенные системы или CygWin в меньшей степени), вы будете знать, что делать, если этого требует особая ситуация. Например, если вы звоните
cat
много раз в секунду (кстати, если вы все-таки оказались в таком положении, спросите себя, является ли bash подходящим инструментом для работы). Опять же, хотя: «сначала заставьте его работать правильно, а затем оптимизируйте его при необходимости» .А как вы объясняете цунами жалоб на UUoC Ника?
Помимо того, что не у всех есть свой вкус, я полагаю, что основная причина, по которой многие люди жалуются на UUoC, не техническая, а человеческая: большинство новичков в Unix не знают об этой
< file command
идиоме, поэтому более искушенному человеку хочется сыграть в «Старого гуру». " им. У него также будет возможность использовать причудливые слова («вызов процесса») и коснуться дорогой темы «оптимизация». Хорошее впечатление гарантировано, поэтому очень трудно устоять. Тогда новички примут совет Гуру за чистую монету и в течение долгого времени передадут его другим как «Единственная Истина» (и проголосуйте за этот ответ :-). Забавное примечание: вероятно, так легко исправить bash, чтобы избежать неэффективности UUoC, поэтому возникает вопрос, почему никто не добавил эту функцию или не сделал< filename
кошка файл после стольких лет. Темная душа предположила бы, что некоторые хакеры с седой бородой хотели бы оставить возможность насмехаться над нами ;-)источник
Что было бы действительно хорошо, так это оболочка, которая поддерживает синтаксис, такой как:
Между тем, я думаю, что
cat filename | realcmd1...
это приемлемо, так как он поддерживает синтаксис, стандартизированный с начальными командами, которые требуют имя файла в качестве аргумента.источник
< filename cmd | cmd2 ...
. Это достаточно близко?< file command ...
по крайней мере, с середины 80-х и, вероятно, еще с 70-х годов, когдаsh
был написан оригинал . В более общем случае, перенаправления ввода / вывода анализируются слева направо и могут перемежаться в любом порядке в командной строке. Такcmd <file arg arg...
что, также будет в силе.Для всех, кто говорит, что кошку приемлемо использовать, потому что она «пахнет» лучше или «более читабельна», я бы сказал следующее:
Возможно, для вас ... но не для тех, кто может читать или пытаться понять ваш код. Если вы никогда не будете пытаться наставлять других своими примерами или делиться своим кодом, тогда обязательно используйте его на досуге.
Я также добавлю этот комментарий, так как давний пользователь Linux и администратор / инженер ... (и нас много), это заставляет нас кровоточить, когда мы видим это. Зачем? Потому что он использует ресурсы в системах, над которыми мы жестко контролируем ресурсы. Команда cat и сам канал используют дополнительную память и файловые дескрипторы, которые совершенно бесполезны. Вы связали ресурсы, которые нужны моей системе бесплатно, и вы НИЧЕГО не получили, что может объяснить использование этих ресурсов. Это огромное нет нет.
Теперь я могу сидеть здесь и обсуждать такие вещи, как запах кода или удобочитаемость, с кем угодно, но в конце концов, это вопрос записи или ошибки, и каждый раз, когда вы используете ресурсы в системе и ничего не получаете за это ... это неверно.
Как домашний пользователь, вы можете учиться на моих советах и узнавать, как лучше делать что-либо, или вы можете выбрать ослепление "запахом" кошек, ваш выбор ... но знайте, что если вы будете открыто использовать эту практику, вас будут звать на этой практике все время, и вам придется молча признать, что они правы, а вы упрямы, потому что это правда. :-)
источник
cat foo.txt | ...
. Другой ответ хорошо объясняет, почему это может быть полезным. Простая сводка дела в пользу: «$ CPU time << $ Brain time» (как прокомментировал @MikeP выше).