Почему есть / bin / echo и почему я хочу его использовать?

47

Я заметил, что существует бинарный исполняемый файл /bin/echo в моей системе Ubuntu MATE 17.04.

Я подумал, что это странно, потому что

$ type echo
echo is a shell builtin

Курсорное тестирование показывает, что /bin/echo делает то же самое, что и Bash builtin echo :

$ /bin/echo foo
foo
$ /bin/echo $USER
zanna

Итак, почему существует другая версия echo , отдельная от программы Bash, и почему и когда я хочу ее использовать?

    
задан Zanna 30.09.2017 в 17:46
источник

2 ответа

86

Если вы откроете приглашение bash и введите echo , которая использует shell builtin вместо запуска /bin/echo , Причинами, по-прежнему важными для существования /bin/echo , являются:

  1. Вы не всегда используете оболочку. В различных обстоятельствах вы запускаете исполняемый файл напрямую, а не через оболочку.
  2. По крайней мере теоретически некоторые оболочки не имеют echo builtin. Это фактически не требуется.

Чтобы перейти на # 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= line файл .desktop . Другой пример - когда вы запускаете sudo echo , что может быть полезно для тестирования, если работает sudo .

Аналогично, некоторые оболочки имеют printf builtin, но /usr/bin/printf также существует.

Менее распространенная причина, по которой вы могли бы сознательно использовать /bin/echo , - это если вы полагаетесь на различия между ней и командой echo , предоставленной вашей оболочкой. man echo документы /bin/echo ; help echo в bash документирует bash builtin. echo не очень переносимо, потому что различные реализации - как в операционных системах, так и в оболочках в одной и той же операционной системе - поддерживают различные параметры (например, -e ) и отличаются в обращении с обратной косой чертой , Конечно, лучше не полагаться на такие детали и использовать printf , а гораздо более портативный .

В bash вы можете сделать type builtin show /bin/echo также - если /bin находится в вашем $PATH , как это всегда должно быть - передать флаг -a :

$ type -a echo
echo is a shell builtin
echo is /bin/echo
    
ответ дан Eliah Kagan 30.09.2017 в 17:55
источник
31

Eliah сделала отличную работу, чтобы ответить на это, но я хочу прокомментировать «почему есть другая версия 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 не нуждаются , чтобы быть встроенными: они не делают ничего, что только встроенный может (влиять или получать состояние оболочки, недоступное внешним командам). % Of_de% Bash, по крайней мере, использует встроенную функцию: printf сохраняет результат переменной printf -v var . var в bash также является особенным: если вы являетесь ключевым словом, вы можете использовать произвольные списки команд в bash (тире нет эквивалента time ). time не обязательно должно быть встроенным: любая внешняя команда наследует текущий рабочий каталог (и это внешняя команда ). pwd - исключение - вам нужен NOP, а : - это. Остальные делают действия, которые может легко выполнить внешняя команда.

Итак, пятая часть этих встроенных функций не должна быть встроена. Тогда почему? : manpage * фактически объясняет, почему это встроенные функции (выделение мой):

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).

Это в значительной степени: эти встроенные функции существуют потому, что они используются так часто, интерактивно и в скриптах, и их функциональность достаточно проста, что оболочка может выполнять эту работу. И так происходит: некоторые (большинство?) Оболочек взяли на себя работу. ** Вернитесь к dash из 2.9 BSD , и вы не найдете sh builtin.

Итак, вполне возможно, что минимальная оболочка может пропустить реализацию таких команд, как встроенные (я не думаю, что какая-либо текущая оболочка делает). Проект GNU coreutils не предполагает, что вы собираетесь запускать их в определенной оболочке, а POSIX требует этих команд. Таким образом, coreutils предоставляет все это и пропускает те, которые не имеют никакого значения вне оболочки.

* Это почти идентично соответствующий текст man-страницы для оболочки Almquist , в основе которой лежит дешифрование оболочки Debian Almquist.

** echo доводит эту идею до крайности: команды, которые вы получаете, загружая различные модули, например zsh , - это то, о чем вы бы не подумали, что оболочка нуждается даже в работе . В этот момент возникает реальный вопрос: зачем вы используете bash вместо zsh, который имеет все эти встроенные функции?

    
ответ дан muru 30.09.2017 в 22:19