Написание сценариев оболочки, которые будут выполняться на любой оболочке (используя несколько строк shebang?)
Я только начал углубляться в shell-скрипты, и я всегда просто бросал свой скрипт в файл, отмечал его chmod +x
а затем делал /path/to/script.sh
и позволял любому интерпретатору по умолчанию иметь свой путь С ним, который я предположил, был zsh, потому что это то, что я использовал для своей оболочки. По-видимому, кажется, что это просто /bin/sh
по умолчанию, даже если я запускаю скрипт из приглашения zsh, потому что я начал помещать zsh-специфические вещи в свои скрипты, и это не сработает, если я не запустил zsh /path/to/script.sh
,
Чтобы понять, вот мои вопросы:
- Какая оболочка выполняет скрипты, когда в начале нет линии shebang (
#!/path/to/shell
)? Я предполагаю/bin/sh
но я не могу подтвердить. - Что считается «передовой практикой» в плане написания сценариев оболочки, которые будут работать на любой платформе? (Хорошо, это своего рода открытый)
-
Можно ли написать скрипт, который пытается использовать zsh и возвращается к bash, если zsh недоступен? Я попытался поместить две строки shebang, как показано ниже, но это просто ошибки с
bad interpreter: /bin/zsh: no such file or directory
, если я попробую его на машине без zsh.- Как я могу получить автозаполнение zsh для заполнения подстановочных знаков, таких как bash?
- Как мне получить завершение aws cli для работы с zsh на ubuntu?
- Пользовательская подсказка Tmux и ZSH: ошибка с именем окна
- Как удалить файлы в командной строке с регулярными выражениями?
- Какие функции zsh вы используете?
#!/bin/zsh
#!/bin/bash
- Команды npm не работают на WSL с zsh
- Изменение заголовков и заголовков iTerm2 в zsh
- Zsh начинается невероятно медленно
- Как проверить, что замедляет мой запуск терминала?
- Zsh не попадает ~ / .profile
- Как заставить Zsh не сохранять неудачную команду
- префикс глобального пути npm
- Файл трубопровода для команды, которая не реализует трубопроводы
Какая оболочка выполняет скрипты, когда в начале нет линии 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
если ваш сценарий является довольно общим для всех оболочек.