Написание сценариев оболочки, которые будут выполняться на любой оболочке (используя несколько строк shebang?)

Я только начал углубляться в shell-скрипты, и я всегда просто бросал свой скрипт в файл, отмечал его chmod +x а затем делал /path/to/script.sh и позволял любому интерпретатору по умолчанию иметь свой путь С ним, который я предположил, был zsh, потому что это то, что я использовал для своей оболочки. По-видимому, кажется, что это просто /bin/sh по умолчанию, даже если я запускаю скрипт из приглашения zsh, потому что я начал помещать zsh-специфические вещи в свои скрипты, и это не сработает, если я не запустил zsh /path/to/script.sh ,

Чтобы понять, вот мои вопросы:

  1. Какая оболочка выполняет скрипты, когда в начале нет линии shebang ( #!/path/to/shell )? Я предполагаю /bin/sh но я не могу подтвердить.
  2. Что считается «передовой практикой» в плане написания сценариев оболочки, которые будут работать на любой платформе? (Хорошо, это своего рода открытый)
  3. Можно ли написать скрипт, который пытается использовать zsh и возвращается к bash, если zsh недоступен? Я попытался поместить две строки shebang, как показано ниже, но это просто ошибки с bad interpreter: /bin/zsh: no such file or directory , если я попробую его на машине без zsh.

    #!/bin/zsh

    #!/bin/bash

Какая оболочка выполняет скрипты, когда в начале нет линии shebang (#! / Path / to / shell)? Я предполагаю / bin / sh, но я не могу подтвердить.

Ядро отказывается выполнять такие скрипты и возвращает ENOEXEC, поэтому точное поведение зависит от программы, с которой вы запускаете такой скрипт.

  • Bash 4.2.39 – использует себя
  • Busybox-ash 1.20.2 – использует себя
  • Тире 0.5.7 – пробеги / bin / sh
  • Рыба 1.23.1 – жалуется на ENOEXEC, а затем обвиняет неправильный файл
  • AT & T ksh 93u + 2012.08.01 – использует себя
  • Mksh R40f – работает / bin / sh
  • Pdksh 5.2.14 – run / bin / sh
  • Sh-heirloom 050706 – использует себя
  • Tcsh 6.18.01 – работает / bin / sh
  • Zsh 5.0.0 – работает / bin / sh
  • Cmd.exe 5.1.2600 – выглядит смешно.

В glibc функции execv() или execve() просто возвращают ENOEXEC. Но execvp() скрывает этот код ошибки и автоматически вызывает / bin / sh. (Это описано в exec (3p) .)

Что считается «передовой практикой» в плане написания сценариев оболочки, которые будут работать на любой платформе? (Хорошо, это своего рода открытый)

Либо придерживайтесь sh и только POSIX-определенных функций, либо просто переходите к полному bash (который широко доступен) и упоминайте его в ваших требованиях при его распространении.

(Теперь, когда я думаю об этом, Perl – или, возможно, Python – будет еще более портативным, не говоря уже о более сильном синтаксисе).

Всегда добавляйте линию shebang. Если вы используете bash или zsh, используйте #!/usr/bin/env bash вместо hardcoding пути оболочки. (Тем не менее, оболочка POSIX гарантирована в /bin/sh , поэтому в этом случае пропустите env .)

(К сожалению, даже /bin/sh не всегда одинаковы. Программа GNU autoconf должна иметь дело со многими различными причудами .)

Можно ли написать скрипт, который пытается использовать zsh и возвращается к bash, если zsh недоступен? Я попытался поместить две строки shebang, как показано ниже, но это просто ошибки с плохим интерпретатором: / bin / zsh: нет такого файла или каталога , если я попробую его на машине без zsh.

Там может быть только одна линия shebang; Все после того, как символ новой строки даже не читается ядром и рассматривается как комментарий оболочек.

Можно написать сценарий, который работает как #!/bin/sh , проверяет, какая оболочка доступна, и запускает exec zsh "$0" "$@" или exec bash "$0" "$@" зависимости от результата. Однако синтаксис, используемый bash и zsh, настолько различен в разных местах, что я бы не рекомендовал делать это для вашего собственного здравомыслия.

1) Текущая оболочка, в которой вы работаете. (Любая оболочка, которая может быть)

2) Придерживайтесь того же типа корпуса (bash / dash / ash / csh / независимо от вашего вкуса) и убедитесь, что ваши поддерживаемые платформы устанавливают оболочку, которую вы хотите использовать по умолчанию. Кроме того, попробуйте использовать общедоступные команды в системах. Избегайте параметров, специфичных для машины.

3) В interpreter directive не существует логики «if-then-else». Вы должны указать оболочку, которая должна существовать во всех системах, которые вы хотите поддерживать … т.е. #!/bin/bash или указать общий #!/bin/sh если ваш сценарий является довольно общим для всех оболочек.

  • Поместить в bash или zsh history абсолютный путь к файлам, над которыми я работаю
  • Invoke zsh, затем * source * другой файл (при входе в интерактивный режим)
  • Как настроить zim vim mode?
  • Как сделать Ctrl-Z и bg одним нажатием клавиши, чтобы процесс продолжался в фоновом режиме?
  • Как использовать sudo с псевдонимом в zsh?
  • Команда команды Git ведет себя как «меньше»,
  • Добавление файла jar в CLASSPATH по-прежнему не выполняется
  • Scp с zsh: совпадений не найдено
  • Как установить короткую ссылку symlink на Sublime Text 3 в терминале?
  • Повторите последнюю команду, соответствующую «двум словам» zsh
  • Завершение истории oh-my-zsh
  • Interesting Posts

    rails, встроенные в проверку даты и времени

    Принуждение сохранения в виде диалога из любого веб-браузера из приложения JSF

    Получить список подкаталогов в VBA

    TableModelListener и проверка нескольких столбцов

    Сеть WiFi отлично подходит для Macbook Pro и Win XP, но Win Vista «Ограниченная связь»

    Портативный программный инструмент для вывода звука на микрофонный вход

    Удалить настройку Safari / Chrome textinput / textarea

    Как получить силу сигнала сотовой связи в Android?

    Открывается автоматическая клавиатура Android на экране

    Выполнение выполнения команды в PowerShell

    Как отключить сглаживание шрифтов только для gnome-terminal, но не для других приложений?

    Заменить значение для выбранной ячейки в pandas DataFrame без использования индекса

    Как создать пользовательское меню «Shapes» в Powerpoint

    Имя classа Java, содержащее знак доллара, не может быть скомпилировано, если присутствует внутренний class

    Как использовать тему Holo.Light и вернуться к «Свету» на устройствах с предварительной сотой?

    Давайте будем гением компьютера.