Какая оболочка выполняет сценарии, когда в начале нет строки shebang (#! / Path / to / shell)? Я предполагаю / bin / sh, но я не могу подтвердить.
Ядро отказывается выполнять такие сценарии и возвращает ENOEXEC, поэтому точное поведение зависит от программы запуска такого сценария из .
- Баш 4.2.39 - использует себя
- busybox-ash 1.20.2 - использует сам
- тире 0.5.7 - пробеги / бин / ш
- fish 1.23.1 - жалуется на ENOEXEC, затем обвиняет не тот файл
- AT & T ksh 93u + 2012.08.01 - использует себя
- мкш R40f - работает / бин / ш
- pdksh 5.2.14 - работает / 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 - будет еще более переносимым, не говоря уже о лучшем синтаксисе.)
Всегда добавляйте строку Шебанга. Если вы используете bash или zsh, используйте #!/usr/bin/env bash
вместо жесткого кодирования путь оболочки. (Тем не менее, оболочка POSIX гарантированно будет в /bin/sh
, так что пропустите env
в этом случае.)
(К сожалению, даже /bin/sh
не всегда одно и то же. Программа GNU autoconf имеет дело со многими разными причудами .)
Можно ли написать скрипт, который пытается использовать zsh и возвращается к bash, если zsh недоступен? Я попытался поместить две строки shebang, как показано ниже, но это просто ошибки с плохим интерпретатором: / bin / zsh: нет такого файла или каталога , если я попробую его на машине без zsh.
Может быть только одна линия Шебанга; все, что находится после символа новой строки, даже не читается ядром, а интерпретируется оболочкой как комментарий.
Это можно написать скрипт , который работает , как #!/bin/sh
, проверки которых оболочка доступно, и работает exec zsh "$0" "$@"
или в exec bash "$0" "$@"
зависимости от результата. Однако синтаксис, используемый bash и zsh, настолько различен в разных местах, что я бы не советовал делать это для вашего же здравомыслия.
strace -f -e fork,clone,execve
. Некоторые снаряды продолжали исполняться/bin/sh
после неудачи; другие интерпретировали сценарий сами.readlink /proc/$$/exe
.csh
иtcsh
поведение зависит от того, начинается ли сценарий#
(в этом случае они вызывают себя вместо sh для интерпретации сценария). Это восходит к тому времени, когда csh поддерживал комментарии, но не оболочку Bourne, поэтому#
намек на то, что это был csh-скрипт.1) текущая оболочка, в которой вы работаете.
2) Используйте тот же тип оболочки (bash / dash / ash / csh / независимо от вашего вкуса) и убедитесь, что ваши "поддерживаемые платформы" устанавливают оболочку, которую вы хотите использовать по умолчанию. Также попробуйте использовать общедоступные команды в системах. Избегайте машинно-специфических опций.
3) В действительности нет логики «если бы тогда»
interpreter directive
. Вы должны указать оболочку, которая должна существовать во всех системах, которые вы хотите поддерживать ... т.е.#!/bin/bash
или указать универсальный,#!/bin/sh
если ваш скрипт достаточно универсален для всех оболочек.источник