Страницы

Поиск по вопросам

воскресенье, 24 ноября 2019 г.

В чём смысл и преимущества #!/usr/bin/env?


Этак с начала времён (юниксовых, т.е. 1.01.1970) в начале скрипта рекомендовалос
использовать shebang / hashbang - строку, указывающую на используемый интерпретатор, например:

#!/bin/bash
echo 'hello world'

#!/usr/bin/python
print 'hello world'

#!/usr/bin/python3
print('hello world')


Недавно наткнулся на рекомендацию использовать вместо этого такую форму:

#!/usr/bin/env bash
echo 'hello world'

#!/usr/bin/env python
print 'hello world'

#!/usr/bin/env python3
print('hello world')


Пожалуйста, объясните, как это работает и в чём преимущества такого подхода? Есл
есть ограничения и/или недостатки по сравнению с обычным способом - то и о них хотелось бы услышать.
    


Ответы

Ответ 1



Основная идея - улучшение переносимости. Не гарантируется, что на различных системах исполняемый файл будет лежать по пути, который указан в shebang. Использование env позволяет снизить этот риск за счет запуска команды на основе данных из переменной среды PATH Более того, если по каким-либо причинам вместо стандартного исполняемого файла пользовател хочет использовать свой, то ему достаточно добавить путь к этому файлу в PATH без необходимости исправления скриптов: ~ $ cp /bin/bash /home/soon/python ~ $ export PATH=/home/soon:$PATH ~ $ env python [soon@archlinux ~]$ exit В примере выше я скопировал bash к себе в домашнюю директорию (переименовав при это файл в python), добавил путь в PATH и запустил python с помощью env, которая усужливо запустила bash, т.к. нашла его раньше. Еще одним примером является использование виртуальных окружений при разработке н Python (virtualenv). Поскольку они также перебивают PATH, env позволяет использовать нужную версию исполняемого файла: ~ $ workon black-box-challenge-2016-py2 ~ (venv:black-box-challenge-2016-py2) $ env python Python 2.7.11 (default, Mar 31 2016, 06:18:34) [GCC 5.3.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> print sys.executable /home/soon/.virtualenvs/black-box-challenge-2016-py2/bin/python >>>

Ответ 2



краткое резюме из информации, приведённой в ответах к этому вопросу и к аналогичным вопросам: Why is it better to use “#!/usr/bin/env NAME” instead of “#!/path/to/NAME” as my shebang? Why is #!/usr/bin/env bash superior to #!/bin/bash? преимущества: будет запущена программа не из конкретно указанного файла, а из того, что встретитс первым в списке каталогов, заданных переменной окружения PATH пользователя, запустившего скрипт. полезно для случаев, когда по указанному пути в системе, на которой будет выполнятьс скрипт, такого файла нет, или когда пользователь модифицирует эту переменную окружения для того, чтобы выполнялась какая-то особая программа (другая реализация, другая версия). недостатки: будет запущена программа не из конкретно указанного файла, а из того, что встретитс первым в списке каталогов, заданных переменной окружения PATH пользователя, запустившего скрипт. например, разные пользователи (или тот же пользователь, но с модифицированным содержимы этой переменной окружения) могут получить разные результаты выполнения одного и того же скрипта. программы /usr/bin/env может не существовать в системе, где будет запускаться скрипт, соответственно, попытка запуска будет неудачной. нельзя будет указать дополнительной опции для выполняемой программы. так получится: #!/путь/к/программе опция а так — нет: #!/usr/bin/env программа опция

Ответ 3



Это связано с переносимостью скриптов. Дело в том, что путь к python, к примеру на разных системах может отличаться, а вот путь к env на всех системах неизменный. Поэтому вызывая env и передавая ей в качестве аргумента нужный интерпретатор, можно быть уверенным, что скрипт будет запущен вне зависимости от того, где на самом деле находится интерпретатор (главное, чтобы он был в PATH).

Ответ 4



Команда env отображает текущие переменые окружения. А если стоит с командой env bash то выполняет команду с текущеми перемеными окружения. В некоторых системах при запуске интерпритаторов используется не текущие перемены окружения , а считываются из файлов или даже ставятся по умолчанию. И если Вы изменили или добавили переменые окружения , то они не будут учтены в запускаемом скрипте, а при запуске через env все переменые будут учтены.

Комментариев нет:

Отправить комментарий