Я заметил, что существует двоичный исполняемый файл /bin/echo
на моем ПОМОЩНИКЕ Ubuntu 17,04 систем.
Я думал, это нечетно, потому что
$ type echo
echo is a shell builtin
Поверхностное тестирование предлагает это /bin/echo
делает тот же вид вещи как встроенный Bash echo
:
$ /bin/echo foo
foo
$ /bin/echo $USER
zanna
Так, почему там другая версия echo
отдельный от программы Bash, и почему или когда я хотел бы использовать его?
Если открыть приглашение 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
вы можете сделать встроенный тип
show / bin / echo
также - предполагая, что / bin
находится в вашем $ PATH
, как всегда должно быть - -с помощью передавая ему -a
флаг :
$ type -a echo
echo is a shell builtin
echo is /bin/echo
Элиа отлично ответил на этот вопрос, но я хочу прокомментировать «Почему существует другая версия echo
, отдельная от программы Bash». Это неправильный вопрос.
Правильный вопрос: почему это вообще встроенная команда , когда она могла быть (и остается) прекрасной внешней командой?
Для простоты, взгляните на встроенные команды в тире, жалкие 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
не не требуется, чтобы были встроенными: они не делают ничего, что может делать только встроенная функция (влиять или получать состояние оболочки, недоступное для внешних команд). printf
Баша, по крайней мере, использует преимущества встроенной функции: printf -v var
сохраняет вывод в переменную var
. time
в bash также является особенным: будучи ключевым словом, вы можете синхронизировать произвольные списки команд в bash (тире не имеет эквивалента time
). pwd
также не обязательно должен быть встроенным - любая внешняя команда унаследует текущий рабочий каталог (и это также внешняя команда ). :
- исключение - вам нужен NOP, и :
он. Остальные выполняют действия, которые может легко выполнить внешняя команда.
Таким образом, пятая часть этих встроенных команд не должна быть встроенной. Почему тогда? dash
man-страница * на самом деле объясняет попутно, почему это встроенные команды (выделено мной):
Builtins This section lists the builtin commands which are builtin because they need to perform some operation that can't be performed by a separate process. In addition to these, there are several other commands that may be builtin for efficiency (e.g. printf(1), echo(1), test(1), etc).
Вот и все: эти встроенные команды существуют, потому что они используются очень часто в интерактивном режиме и в скриптах, и их функциональность достаточно проста, чтобы оболочка могла выполнять эту работу. Так и случилось: некоторые (большинство?) Оболочек взяли на себя эту работу. ** Вернитесь к sh
из 2.9 BSD , и вы не найдете встроенная функция echo
.
Итак,вполне возможно, что минимальная оболочка может пропустить реализацию таких команд как встроенные (хотя я не думаю, что какая-либо текущая оболочка это делает). Проект GNU coreutils не предполагает, что вы собираетесь запускать их в определенной оболочке, а POSIX требует этих команд. Таким образом, coreutils все равно предоставляет их и пропускает те, которые не имеют никакого значения за пределами оболочки.
* Это почти идентично тексту соответствующей страницы руководства для оболочки Almquist , что означает тире , оболочка Debian Almquist, основана на.
** zsh
доводит эту идею до крайности: команды, которые вы получаете при загрузке различных модулей, например zmv
, такие вещи, о которых вы даже не подумали бы, даже если оболочка . В этот момент возникает реальный вопрос: зачем вам использовать bash вместо zsh, в котором есть все эти встроенные команды?