В чем разница использования #! / Usr / bin / env или #! / Bin / env в shebang? - PullRequest
14 голосов
/ 05 апреля 2011

Будет ли какая-то разница или это просто личный выбор?

Ответы [ 4 ]

14 голосов
/ 05 апреля 2011

#!<interpreter> <arguments> пытается запустить <interpreter> <arguments>, чтобы прочитать и запустить остальную часть файла.

То есть #!/usr/bin/env означает, что должна быть программа с именем /usr/bin/env;
#!/bin/env означает, что должна быть программа с именем /bin/env.

Некоторые системы имеют одну, а другую нет.

По моему опыту, большинство имеют /usr/bin/env, поэтому #!/usr/bin/env встречается чаще.

Системы Unix будут пытаться запустить <interpreter>, используя execve, поэтому он должен быть полным путем, а #!env без пути не будет работать.

2 голосов
/ 05 декабря 2012

Объяснение Микеля великолепно, оно пропускает лишь небольшой факт (что довольно важно), передается только один аргумент, включая все пробелы:

#!<Interpreter> <argument>

Результаты вызова:

$ <Interpreter> '<argument>' path_to_calling_script

Так, например:

$ cat /tmp/test
#!/usr/bin/env python
print "hi"

$ /tmp/test

- это то же самое, что и вызов:

$ /usr/bin/env "python" /tmp/test

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

 #!/bin/bash -c /bin/env python

Будет интерпретироваться как:

 $ /bin/bash "-c /bin/env python"

Что не будет работать.

1 голос
/ 05 апреля 2011

/usr/bin/env - это мягкая ссылка на /bin/env. По сути, вы используете /bin/env

0 голосов
/ 16 апреля 2019

Исторически в UNIX было 2 набора двоичных файлов:

  • / файловая система, смонтированная на ранних этапах загрузки.
  • /usr возможно, был смонтирован позже, возможно, запустив сценарии и программы из / для организации монтирования. Пример: некоторые сайты сэкономили место, подключив / usr из сети, но сначала вам нужно войти в сеть. Пример: это большая локальная файловая система, но если она повреждена, вам нужны такие инструменты, как fsck, чтобы попытаться исправить ее.

Таким образом, /bin и /sbin (используя /lib) должны были содержать минимальную систему, включающую по крайней мере оболочку в / bin / sh, основы сценариев, такие как /bin/echo, /bin/test и т. Д., System инструменты типа /bin/mount или /sbin/mount и /bin/fsck ...

Таким образом, в разных Unix, почти любая программа могла бы быть:

  • в / usr / bin / но НЕ / bin
  • в / bin, но НЕ / usr / bin
  • в обоих, так же, как символическая ссылка
  • в обоих, но разных! Например. в некоторых системах игра /bin/sh была очень минимальной оболочкой (например, dash) для более быстрого запуска, но символическая ссылка /usr/bin/sh -> /usr/bin/bash (iirc, вызывая bash как «sh», переводит его в какой-то режим posix, но это все еще другая более мощная оболочка).

Таким образом, хитрость использования env для написания переносимых скриптов - env просто делает поиск в PATH. (Это также полезно в других местах, которые не выполняют поиск PATH, например, docker exec.)

Что изменилось

Это были допустимые варианты использования, но современный Linux следовал аналогичному аргументу «нужно небольшое пользовательское пространство для монтирования / восстановления основного пользовательского пространства» и для самого /! Были введены системный вызов Pivot и initrd, и число инструментов для копирования в него необходимых вам деталей возросло.

/ usr унификация

Теперь / против /usr возможно утратили свою цель. Наличие как на одной файловой системе, так и символических ссылок было выполнимо для всех в принципе , хотя некоторые конкретные установки сломались бы и должны были измениться ...

См. https://lwn.net/Articles/483921/ от 2012 г. для обзора этой идеи "/ usr unification". Например, Fedora завершила это: https://fedoraproject.org/wiki/Features/UsrMove. Многие другие дистрибутивы не имеют или все еще обсуждают его, или сглаживают некоторые виды, чтобы сломать меньше пользователей. Например, смотрите подготовку к Debian: https://wiki.debian.org/UsrMerge.

...