Почему есть /bin/echo и зачем мне его использовать?
Я заметил, что есть исполняемый двоичный файл /bin/echo
в моей системе Ubuntu MATE 17.04.
Я думал, это странно, потому что
$ type echo
echo is a shell builtin
Беглый тест предполагает, что /bin/echo
делает то же самое, что встроенный в Bash echo
:
$ /bin/echo foo
foo
$ /bin/echo $USER
zanna
Итак, почему есть другая версия echo
отдельно от программы Bash, и почему или когда я хочу ее использовать?
2 ответа
Если вы откроете bash
подскажите и введите echo
команда, которая использует встроенную оболочку вместо запуска /bin/echo
, Причины, которые все еще важны для /bin/echo
существовать являются:
- Вы не всегда используете оболочку. При различных обстоятельствах вы запускаете исполняемый файл напрямую, а не через оболочку.
- По крайней мере, в теории, некоторые оболочки не имеют
echo
встроенный. Это на самом деле не требуется.
Чтобы расширить #1, предположим, что вы хотите переместить все обычные файлы, имена которых начинаются с abc
где-нибудь в src
в dest
, Есть несколько способов сделать это, но один из них:
find src -name 'abc*' -type f -exec mv -nv {} dest/ \;
Но предположим, что вместо того, чтобы просто выполнить это, вы хотите видеть каждую команду, которая будет выполняться первой. Ну, тогда вы можете подготовить echo
к команде, как вы могли бы в других контекстах:
find src -name 'abc*' -type f -exec echo mv -nv {} dest/ \;
Но find
не использует оболочку Это работает /bin/echo
,
Кроме того find
с -exec
или же -execdir
, /bin/echo
Исполняемый файл будет вызываться другими программами, которые сами запускают программы, но не через оболочку. Это происходит с xargs
команда (которая связана с find
), а также в ряде других контекстов, таких как Exec=
линия .desktop
файл Другой пример, когда вы запускаете sudo echo
, что может быть удобно для тестирования, если sudo
работает.
Аналогично, некоторые снаряды имеют printf
встроенный но /usr/bin/printf
также существует.
Менее распространенная возможная причина, которую вы могли бы сознательно использовать /bin/echo
если вы полагались на различия между ним и echo
Команда, предоставляемая вашей оболочкой. man echo
документы /bin/echo
; help echo
в bash
документы bash
встроенный. echo
не очень переносим, потому что разные реализации - как в операционных системах, так и в оболочках в одной и той же операционной системе - поддерживают разные варианты (например, -e
) и отличаются в своем лечении от обратного слеша. Конечно, лучше избегать полагаться на такие детали и использовать printf
вместо этого, который является намного более портативным.
В bash
Вы можете сделать type
встроенное шоу /bin/echo
а также - при условии /bin
в вашем $PATH
как всегда должно быть - передавая -a
флаг:
$ type -a echo
echo is a shell builtin
echo is /bin/echo
Элия отлично справился с ответом на этот вопрос, но я хочу прокомментировать вопрос: "Почему существует другая версия? echo
отделить от части программы Bash ". Это неправильный вопрос.
Правильный вопрос: почему это встроенное в первую очередь, когда оно могло быть (и является) совершенно хорошей внешней командой?
Для простоты взгляните на встроенные в dash, жалкие 38 (bash имеет 61, для сравнения, исходя из вывода compgen -b
):
. continue getopts readonly type
: echo hash return ulimit
[ eval jobs set umask
alias exec kill shift unalias
bg exit local test unset
break export printf times wait
cd false pwd trap
command fg read true
Сколько из них должно быть встроено? [
, echo
, false
, printf
, pwd
, test
, а также true
не нужно быть встроенными: они не делают ничего, что может сделать только встроенное (влияет или получает состояние оболочки, которое недоступно для внешних команд). в Bash printf
по крайней мере, пользуется тем, что встроен: printf -v var
сохраняет вывод в переменную var
, time
в bash также особенное: будучи ключевым словом, вы можете синхронизировать произвольные списки команд в bash (у dash нет time
эквивалент). pwd
Не обязательно быть встроенным - любая внешняя команда наследует текущий рабочий каталог (и это тоже внешняя команда). :
исключение - вам нужен NOP, и :
это. Остальные выполняют действия, которые легко может выполнить внешняя команда.
Таким образом, пятая часть этих встроенных функций не должна быть встроенной. Тогда почему? dash
manpage * на самом деле попутно объясняет, почему это buildins (выделено мое):
Встроенные команды В этом разделе перечислены встроенные команды, которые встроены, потому что они необходимо выполнить некоторые операции, которые не могут быть выполнены отдельным процесс. В дополнение к этому есть несколько других команд, которые могут быть встроенным для эффективности (например, printf(1), echo(1), test(1) и т. д.).
Вот и все: эти встроенные функции существуют потому, что они используются так часто, в интерактивном режиме и в сценариях, а их функциональные возможности достаточно просты, чтобы оболочка могла выполнять свою работу. И так получилось: некоторые (большинство?) Снаряды взялись за работу.** Вернитесь к sh
от 2.9 BSD, и вы не найдете echo
встроенный.
Таким образом, вполне возможно, что минимальная оболочка может пропустить реализацию таких команд, как встроенные (хотя я не думаю, что какая-либо текущая оболочка это делает). Проект GNU coreutils не предполагает, что вы собираетесь запускать их в определенной оболочке, а POSIX требует этих команд. Итак, coreutils предоставляет их в любом случае и пропускает те, которые не имеют никакого значения вне оболочки.
* Это почти идентично соответствующему тексту man-страницы для оболочки Almquist, на которой основана черта, оболочка Debian Almquist.
** zsh
доводит эту идею до крайности: команды, которые вы получаете, загружая различные модули, такие как zmv
это вещи, в которые вы даже не думаете, что в оболочку нужно даже попасть. В этот момент реальный вопрос: зачем вам использовать bash вместо zsh, в котором есть все эти встроенные функции?