shebangs с абсолютными путями по умолчанию (POSIX)?

EDIT: вопрос и ответы верны, но проблема, о которой я здесь говорил, – нет. Сопровождающий фактически ОТКАЗАЛ использовать /usr/bin/env в качестве решения и вместо этого воссоздал скрипт как sh , и это нарушило установку других пользователей. Таким образом, использование env для поиска bash не является POSIX, но по умолчанию «достаточно» считается стандартным.

У меня возникли некоторые ошибки при установке программного обеспечения на nixos (в частности, в стеке haskell ), и после некоторых поисков в Интернете я нашел несколько примеров того, как люди столкнулись с определенным путем установки программного обеспечения. Здесь пример, когда сопровождающий вернул модификацию решения /usr/bin/env при поиске bash, поскольку он нарушил установку других пользователей.

Итак, ссылаясь на env на shebang, не сообщая об абсолютном пути установки (опираясь на путь поиска системы), можно считать ошибочным?

Я имею в виду,

 #!env bash 

вместо

 #!/usr/bin/env bash 

если абсолютный путь установки для env сам по себе не является дефолтом для всех систем?

  • Сделайте меньше файлов, возвращенных с помощью команды
  • Опция gnome - terminal -e не выполняется?
  • Извлечь начальные и конечные координаты в соответствии с определенной длиной нефиксированного интервала
  • Unix эквивалент PowerShell?
  • Существует ли стандартная аббревиатура для 'find. -name foo 'или мне нужна функция для этого?
  • Замена переменной подстановки Shell
  • Отладка функций bash
  • выберите одну из двух программ в сценарии bash
  • 2 Solutions collect form web for “shebangs с абсолютными путями по умолчанию (POSIX)?”

    env присутствует в /usr/bin практически во всех Unix-подобных системах, которые до сих пор сохранились в 21 веке. Два исключения, о которых я знаю, – это SCO OpenServer (который по-прежнему поддерживает несколько очень старых серверов) и NextSTEP (не может быть много поддерживаемых аппаратных средств, которые не вымерли). Для переносимости используйте #!/usr/bin/env . Все остальное менее переносимо (за исключением #!/bin/sh , которое имеет свои собственные проблемы и полезно, только если вы планируете запустить свой скрипт на SCO).

    POSIX и Single Unix не определяют /usr/bin/env , или /bin/sh , или любой абсолютный путь, отличный от / , /tmp , и несколько записей в /dev . /usr/bin/env не является официальным стандартом Unix, но это действительно стандарт де-факто.

    #!env абсолютно бесполезен. Поиск Shebang не использует переменную PATH , она выполняется ядром. (И если это сделал PATH-поиск, вы могли бы также написать #!bash напрямую)

    #!/usr/bin/env bash отлично подходит для сценария bash, и я сомневаюсь в мудрости сопровождающего, который отклонил изменение от #!/bin/bash . Похоже, что сопровождающий был взъерошен по просьбе, а затем не воспринял это очень серьезно. Переход на использование стандартного sh вместо bash еще лучше для переносимости, но, видимо, это не сработало (сценарий, вероятно, имел нестандартную конструкцию слева). Если преобразование скрипта для работы в других оболочках было невозможно, сценарий все равно должен был быть изменен для использования #!/usr/bin/env bash вместо #!/bin/bash .

    POSIX не указывает, как именно интерпретировать shebang. Цитирование из семейства функций exec « ОБОСНОВАНИЕ :

    Одна общая историческая реализация заключается в том, что функции execl () , execv () , execle () и execve () возвращают ошибку [ENOEXEC] для любого файла, который не распознается как исполняемый, включая сценарий оболочки. Когда функции execlp () и execvp () сталкиваются с таким файлом, они предполагают, что файл является сценарием оболочки и вызывают известный интерпретатор команд для интерпретации таких файлов. Это требуется POSIX.1-2008. Эти реализации execvp () и execlp () приводят к ошибке [ENOEXEC] в редком случае проблемы с исполняемым файлом интерпретатора команд. Из-за этих реализаций ошибка [ENOEXEC] не упоминается для execlp () или execvp () , хотя реализации все равно могут ее предоставить.

    Другой способ, с помощью которого некоторые исторические реализации обрабатывают сценарии оболочки, – это распознать первые два байта файла в виде символьной строки «#!» и используя оставшуюся часть первой строки файла в качестве имени исполняемого командного интерпретатора.

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

    1. Если файл образа процесса является допустимым исполняемым файлом (в формате, который является исполняемым и действительным и имеет соответствующие права) для этой системы, система выполняет этот файл.

    2. Если файл образа процесса имеет соответствующие права и находится в формате, который является исполняемым, но недействительным для этой системы (например, признанный двоичный код для другой архитектуры), то это ошибка, а errno имеет значение [EINVAL] (см. Ниже ОБОСНОВАНИЕ на [EINVAL]).

    3. Если файл образа процесса имеет соответствующие права, но не распознается иначе:

      1. Если это вызов execlp () или execvp () , они вызывают интерпретатор команд, предполагая, что файл образа процесса является сценарием оболочки.

      2. Если это не вызов execlp () или execvp () , возникает ошибка, а errno – [ENOEXEC].

    И ранее, в ОПИСАНИИ , он говорит, что execlp и execvp должны запускать скрипты с sh :

    В тех случаях, когда другие члены семейства функций exec сбой и установка errno в [ENOEXEC], функции execlp () и execvp () должны выполнять интерпретатор команд, а среда выполняемой команды должна быть такой, как если бы процесс вызывается утилита sh с помощью execl () следующим образом:

     execl(<shell path>, arg0, file, arg1, ..., (char *)0); 

    где < shell path > – неопределенное имя пути для утилиты sh , файл – файл образа процесса, а для execvp () , где arg0 , arg1 и т. д. соответствуют значениям, переданным execvp () в argv [0] , argv 2 и т. д.

    Таким образом, эти функции выполняют эквивалент sh file ... И когда скрипт запускается из оболочки POSIX, последствия shebang не определены. См. 2.1. Введение оболочки :

    1. Оболочка считывает свой вход из файла (см. Sh ), из параметра -c или из функций system () и popen (), определенных в объёме системных интерфейсов POSIX.1-2008. Если первая строка файла команд оболочки начинается с символов « #! », Результаты не заданы.

    Zsh не против, bash делает:

     $ cat foo.sh #! env perl echo $0 $ zsh -c ./foo.sh Can't locate object method "echo" via package "./foo.sh" (perhaps you forgot to load "./foo.sh"?) at ./foo.sh line 2. $ bash -c ./foo.sh bash: ./foo.sh: env: bad interpreter: No such file or directory 

    Не полагайтесь на то, чтобы не указывать запросы PATH в shebang. (Я знаю, что я запускал zsh -c ./foo.sh вместо zsh foo.sh , однако намерение состояло в том, чтобы показать, что оболочки в выполнении команд могут отличаться.)

    Linux и Unix - лучшая ОС в мире.