Если Вы действительно не хотите, чтобы это вмешалось вообще, не помещайте его нигде в Ваш $PATH
.
Если Вы хотите это в $PATH
, по крайней мере, удостоверьтесь, что не установили на /usr/local
. Я нашел, что много программного обеспечения смотрит там, даже если оно установлено дистрибутивом в /usr
.
Мой любимый способ установить пользовательски скомпилированное программное обеспечение находится в моем $HOME
каталог. Тем путем Вы не должны использовать sudo
для чего-либо, и это очень приятно разделяется от остальной части Вашей системы. Например:
mkdir ~/stage
./configure --prefix=/home/username/stage && make && make install
И если Вы хотите, можно затем добавить /home/username/stage/bin
к Вашему $PATH
.
"Категорический" ответ, конечно, принесен Вам Бесполезным Использованием 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, который читает как этот, действительно легко следовать, и отдельные компоненты могут быть отлажены легко в их соответствующих функциях.
Помещение <file
на конце конвейера менее читаемо, чем наличие cat file
в запуске. Естественный английский читает слева направо.
Помещение <file
запуск конвейера также менее читаем, чем кошка, сказал бы я. Слово более читаемо, чем символ, особенно символ, который, кажется, указывает неправильный путь.
Используя cat
сохраняет command | command | command
формат.
<
однажды делает код менее читаемым, так как он уничтожает непротиворечивость синтаксиса мультиконвейера.
– A.Danischewski
29.03.2015, 22:17
<
как это: alias load='<'
и затем используйте, например. load file | sed ...
. Псевдонимы могут использоваться в сценариях после выполнения shopt -s expand_aliases
.
– niieani
03.02.2016, 17:21
Одно из того, на что другие ответы здесь, кажется, не обращались напрямую, это то, что использование 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
, это также дополнительная работа по чтению и записи байтов файла дважды, а не один раз. Теперь, говоря практически и на современных системах, это не имеет большого значения - это может заставить Вашу систему сделать несколько микросекунд ненужной работы. Но если это для скрипта, который вы планируете распространять, потенциально людям, использующим его на машинах, которые и так недостаточно мощные, то несколько микросекунд могут сложиться за много итераций
Вот краткое изложение некоторых недостатков:
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
не будет скомпонован, если не удается открыть файл
.
<file
мог прибыть перед командой. Это решает все мои проблемы! – 08.07.2011, 16:43<file
может прибыть куда угодно в командную строку:<file grep needle
илиgrep <file needle
илиgrep needle <file
. Исключением являются сложные команды, такие как циклы и группировки; там перенаправление должно произойти после закрытияdone
/}
/)
/ и т.д. @Caleb Это содержит во всех оболочках Границы/POSIX. И я не соглашаюсь, что это ужасно. – Gilles 'SO- stop being evil' 09.07.2011, 00:43$(cat /some/file)
с$(< /some/file)
, который делает то же самое, но старается не порождать процесс. – cjm 10.07.2011, 23:27$(< /some/file)
имеет ограниченную мобильность. Это работает в ударе, но не пепле BusyBox, например, или FreeBSD sh. Вероятно, не работает в тире также, так как те последние три оболочки являются всеми близкими родственниками. – dubiousjim 14.11.2012, 21:24