Я должен заботиться о ненужных кошках?

Если Вы действительно не хотите, чтобы это вмешалось вообще, не помещайте его нигде в Ваш $PATH.

Если Вы хотите это в $PATH, по крайней мере, удостоверьтесь, что не установили на /usr/local. Я нашел, что много программного обеспечения смотрит там, даже если оно установлено дистрибутивом в /usr.

Мой любимый способ установить пользовательски скомпилированное программное обеспечение находится в моем $HOME каталог. Тем путем Вы не должны использовать sudo для чего-либо, и это очень приятно разделяется от остальной части Вашей системы. Например:

mkdir ~/stage
./configure --prefix=/home/username/stage && make && make install

И если Вы хотите, можно затем добавить /home/username/stage/bin к Вашему $PATH.

52
09.07.2011, 13:04
4 ответа

"Категорический" ответ, конечно, принесен Вам Бесполезным Использованием cat Премия.

Цель кошки состоит в том, чтобы конкатенировать (или "соединиться"), файлы. Если это - только один файл, связывание его ни с чем вообще является пустой тратой времени и стоит Вам процесса.

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

Большинство программ, как Вы отмечаете, может принять аргумент в пользу входного файла. Однако всегда существует встроенная оболочка < это может использоваться везде, где поток STDIN ожидается, который сохранит Вас один процесс путем выполнения работы в процессе оболочки, который уже работает.

Можно даже стать творческими с тем, ГДЕ Вы пишете это. Обычно это было бы помещено в конце команды перед определением любых выходных перенаправлений или каналов как это:

sed s/blah/blaha/ < data | pipe

Но это не должен быть тот путь. Это может даже быть на первом месте. Например, Ваш пример кода мог быть записан как это:

< data \
    sed s/bla/blaha/ |
    grep blah |
    grep -n babla

Если удобочитаемость сценария является Вашим беспокойством, и Ваш код достаточно грязен что, добавляя строку для cat как ожидают, поможет следовать, существуют другие способы очистить Ваш код. Тот, что я использую много, которое помогает сделать сценарии easiy для выяснения позже, разбивает каналы в логические наборы и сохраняет их в функциях. Код сценария затем становится очень естественным, и любую часть pipline легче отладить.

function fix_blahs () {
    sed s/bla/blaha/ |
    grep blah |
    grep -n babla
}

fix_blahs < data

Вы могли затем продолжить fix_blahs < data | fix_frogs | reorder | format_for_sql. За pipleline, который читает как этот, действительно легко следовать, и отдельные компоненты могут быть отлажены легко в их соответствующих функциях.

49
27.01.2020, 19:33
  • 1
    я не знал это <file мог прибыть перед командой. Это решает все мои проблемы! –   08.07.2011, 16:43
  • 2
    @Tim: Bash и Zsh обе поддержки, что, хотя я думаю, что это ужасно. Когда я волнуюсь по поводу своего кода, являющегося симпатичным и удобным в сопровождении, я обычно использую функции для чистки его. Посмотрите мое последнее редактирование. –  Caleb 08.07.2011, 16:55
  • 3
    @Tim <file может прибыть куда угодно в командную строку: <file grep needle или grep <file needle или grep needle <file. Исключением являются сложные команды, такие как циклы и группировки; там перенаправление должно произойти после закрытия done/}/)/ и т.д. @Caleb Это содержит во всех оболочках Границы/POSIX. И я не соглашаюсь, что это ужасно. –  Gilles 'SO- stop being evil' 09.07.2011, 00:43
  • 4
    @Gilles, в ударе можно заменить $(cat /some/file) с $(< /some/file), который делает то же самое, но старается не порождать процесс. –  cjm 10.07.2011, 23:27
  • 5
    Только подтвердить это $(< /some/file) имеет ограниченную мобильность. Это работает в ударе, но не пепле BusyBox, например, или FreeBSD sh. Вероятно, не работает в тире также, так как те последние три оболочки являются всеми близкими родственниками. –  dubiousjim 14.11.2012, 21:24

Помещение <file на конце конвейера менее читаемо, чем наличие cat file в запуске. Естественный английский читает слева направо.

Помещение <file запуск конвейера также менее читаем, чем кошка, сказал бы я. Слово более читаемо, чем символ, особенно символ, который, кажется, указывает неправильный путь.

Используя cat сохраняет command | command | command формат.

16
27.01.2020, 19:33
  • 1
    я соглашаюсь, с помощью < однажды делает код менее читаемым, так как он уничтожает непротиворечивость синтаксиса мультиконвейера. –  A.Danischewski 29.03.2015, 22:17
  • 2
    @Jim можно решить удобочитаемость путем создания псевдонима к < как это: alias load='<' и затем используйте, например. load file | sed .... Псевдонимы могут использоваться в сценариях после выполнения shopt -s expand_aliases. –  niieani 03.02.2016, 17:21
  • 3
    Да я знаю о псевдонимах. Однако, хотя этот псевдоним заменяет символ словом, это требует, чтобы читатель знал о Вашей персональной установке псевдонима, является не очень портативным - также. –  Jim 04.02.2016, 20:05

Одно из того, на что другие ответы здесь, кажется, не обращались напрямую, это то, что использование cat, как это не "бесполезно" в том смысле, что "порождается посторонний кошачий процесс, который не работает"; это бесполезно в том смысле, что "порождается кошачий процесс, который делает только ненужную работу".

В случае этих двух:

sed 's/foo/bar/' somefile
<somefile sed 's/foo/bar/'

оболочка начинает процесс sed, который читает из какого-то файла или stdin (соответственно), а затем выполняет некоторую обработку - он считывает, пока не попадет на новую строку, заменяет первую "фу" (если таковая имеется) на этой строке на "бар", затем печатает эту строку на stdout и петли.

В случае:

cat somefile | sed 's/foo/bar/'

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

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

.
9
27.01.2020, 19:33

Вот краткое изложение некоторых недостатков:

cat $file | cmd

над

< $file cmd
  • Во-первых, примечание: (намеренно для цели обсуждения) отсутствуют двойные кавычки вокруг $ file выше. В случае cat это всегда проблема, за исключением zsh ; в случае перенаправления это проблема только для bash или ksh88 и, для некоторых других оболочек (включая bash в режиме POSIX) только в интерактивном режиме (не в скриптах).
  • Наиболее часто упоминаемый недостаток заключается в том, что возникает дополнительный процесс. Обратите внимание, что если cmd является builtin, то это даже 2 процессы в некоторых оболочках, таких как bash .
  • По-прежнему на фронте производительности, за исключением оболочек, где cat построен, что также дополнительная команда выполняется (и, конечно, загружается, и инициализируется (и библиотеки, с которыми он также связан)).
  • По-прежнему на фронте производительности, для больших файлов, это означает, что система должна будет поочередно планировать процессы cat и cmd и постоянно заполнять и опустошать буфер канала. Даже если cmd выполняет 1GB большие вызовы системы read () за раз, управление должно будет переходить назад и вперед между cat и cmd , поскольку канал не может одновременно содержать более нескольких килобайт данных.
  • Некоторые cmd (например, wc -c ) могут выполнять некоторые оптимизации, когда их stdin является обычным файлом, который они не могут сделать с cat | cmd , так как их stdin является просто трубой. При использовании cat и канала они также не могут искать () в файле. Для таких команд, как tac или tail , это имеет огромное значение в производительности, так как это означает, что с cat они должны хранить весь ввод в памяти.
  • Файл cat $ и даже его более правильная версия cat -- "$ file" не будут работать должным образом для некоторых конкретных имен файлов, таких как - (или --help или что-либо, начиная с - , если вы забудете - ). Если кто-то настаивает на использовании cat , он, вероятно, должен использовать для надежности cat < "$ file" | cmd .
  • Если $ file не может быть открыт для чтения (доступ запрещен, не существует...), < "$ file" cmd сообщит о непротиворечивом сообщении об ошибке (оболочкой) и не запустить cmd , в то время как cat $ file | cmd все еще будет выполняться cmd Это также означает, что в таких вещах, как < file cmd > file2 , файл file2 не будет скомпонован, если не удается открыть файл .
24
27.01.2020, 19:33

Теги

Похожие вопросы