Можно ли проверить синтаксис сценария bash без его выполнения?
Используя Perl, я могу запустить perl -c 'script name'
. Есть ли эквивалентная команда для сценариев bash?
Можно ли проверить синтаксис сценария bash без его выполнения?
Используя Perl, я могу запустить perl -c 'script name'
. Есть ли эквивалентная команда для сценариев bash?
bash -n scriptname
Возможно, очевидное предостережение: это проверяет синтаксис, но не проверяет, пытается ли ваш bash-скрипт выполнить команду, которой нет в вашем пути, например ech hello
вместо echo hello
.
set
.
- person ephemient; 06.10.2008
if ["$var" == "string" ]
вместо if [ "$var" == "string" ]
- person Brynjar; 05.08.2011
type [
говорит [является встроенной оболочкой. В конечном итоге он делегирует программу test
, но также ожидает закрывающую скобку. Так что это похоже на if test"$var"
, что не то, что имел в виду автор, но синтаксически допустимо (скажем, $var имеет значение a, тогда мы увидим bash: testa: команда не найдена). Дело в том, что синтаксически нет пропущенного пробела.
- person Joshua Cheek; 20.07.2014
[
вызывается только в этом случае, если $var
расширяется до пустой строки. Если $var
заменяется на непустую строку, [
объединяется с этой строкой и интерпретируется как имя команды (а не функции name) от Bash, и да, это синтаксически допустимо, но, как вы утверждаете, явно не намеренно. Если вы используете [[
вместо [
, даже несмотря на то, что [[
является ключевым словом оболочки (а не встроенным), вы получите тот же результат, потому что непреднамеренная конкатенация строк по-прежнему переопределяет распознавание ключевого слова.
- person mklement0; 12.06.2015
["$var"
является синтаксически допустимой командой- имя выражение; аналогично токены ==
и "$string"
являются допустимыми аргументами команды. (Как правило, встроенная команда [
анализируется с синтаксисом command, тогда как [[
— как ключевое слово оболочки — анализируется по-другому.) Встроенная оболочка [
нет делегировать программе test
(внешняя утилита): bash
, dash
, ksh
, zsh
все имеют встроенные версии как [
, так и test
, и они не< /i> вызывать их внешние служебные аналоги.
- person mklement0; 12.06.2015
-n
будет лучшим выбором, но это не позволит выявить многие ошибки, которые могут совершить новички; чтобы отследить их, используйте shellcheck.net или его интерфейс командной строки, как описано в ответ dvd818.
- person mklement0; 12.06.2015
shopt -s extglob
, а затем сделаете foo@(bar|baz))
в case
, bash -n
увидит это как синтаксическую ошибку (bash -s extglob -n
не увидит, но вы никогда не знаете, какая часть скрипта затронута)
- person Alois Mahdal; 02.07.2015
man bash
: -n Read commands but do not execute them. This may be used to check a shell script for syntax errors. This is ignored by interactive shells.
- person wisbucky; 25.03.2019
Время меняет все. Вот веб-сайт, который обеспечивает онлайн-проверку синтаксиса для сценария оболочки.
Я обнаружил, что это очень мощное средство для обнаружения распространенных ошибок.
ShellCheck – это инструмент статического анализа и проверки скриптов sh/bash. В основном он сосредоточен на обработке типичных синтаксических ошибок и ловушек начального и среднего уровня, когда оболочка просто выдает загадочное сообщение об ошибке или странное поведение, но также сообщает о нескольких более сложных проблемах, где крайние случаи могут вызвать отложенные сбои.
Исходный код Haskell доступен на GitHub!
shellcheck
, через Homebrew: brew install shellcheck
.
- person mklement0; 12.06.2015
apt-get install shellcheck
- person that other guy; 31.07.2015
trusty-backports
.
- person Peterino; 05.08.2015
Я также включаю опцию «u» для каждого сценария bash, который я пишу, чтобы выполнить дополнительную проверку:
set -u
Это сообщит об использовании неинициализированных переменных, как в следующем скрипте «check_init.sh».
#!/bin/sh
set -u
message=hello
echo $mesage
Запуск скрипта:
$ check_init.sh
Сообщит следующее:
./check_init.sh[4]: сообщение: Параметр не установлен.
Очень полезно ловить опечатки
set -u
, хотя на самом деле это не отвечает на вопрос, потому что вам нужно запустить скрипт, чтобы получить сообщение об ошибке. Даже bash -n check_init.sh
не показывает это предупреждение
- person rubo77; 06.07.2017
sh -n script-name
Запустите это. Если в скрипте есть какие-либо синтаксические ошибки, он возвращает такое же сообщение об ошибке. Если ошибок нет, то выходит без каких-либо сообщений. Вы можете проверить это немедленно, используя echo $?
, который безошибочно вернет 0
, подтверждающий успешное выполнение.
Это сработало для меня хорошо. Я запускал ОС Linux, Bash Shell.
sh -n
, вероятно, не проверит, является ли сценарий допустимым сценарием Bash. Это может дать ложноотрицательные результаты. sh
- это некий вариант оболочки Bourne, который обычно не является Bash. Например, в Ubuntu Linux realpath -e $(command -v sh)
дает /bin/dash
- person jarno; 04.11.2019
На самом деле я проверяю все сценарии bash в текущем каталоге на наличие синтаксических ошибок БЕЗ запуска их с помощью инструмента find
:
Пример:
find . -name '*.sh' -exec bash -n {} \;
Если вы хотите использовать его для одного файла, просто отредактируйте подстановочный знак с именем файла.
пустая команда [двоеточие] также полезна при отладке, чтобы увидеть значение переменной
set -x
for i in {1..10}; do
let i=i+1
: i=$i
done
set -
set -x
показывает каждую строку перед ее выполнением
- person rubo77; 06.07.2017
Существует плагин BashSupport для IntelliJ IDEA, который проверяет синтаксис.
.sh
или другим расширением, связанным со сценариями Bash, как в случае, если вы создаете сценарии с помощью какого-либо инструмента для создания шаблонов, такого как ERB (тогда они заканчиваются на .erb
). Пожалуйста, проголосуйте за youtrack.jetbrains.com/issue/IDEA-79574, если хотите. фиксированный!
- person Greg Dubicki; 22.09.2016
Если вам нужно указать в переменной допустимость всех файлов в каталоге (перехватчик git pre-commit, сборка скрипта lint), вы можете перехватить вывод stderr команд «sh -n» или «bash -n» (см. ответы) в переменной и иметь "if/else" на основе этого
bashErrLines=$(find bin/ -type f -name '*.sh' -exec sh -n {} \; 2>&1 > /dev/null)
if [ "$bashErrLines" != "" ]; then
# at least one sh file in the bin dir has a syntax error
echo $bashErrLines;
exit;
fi
Замените «sh» на «bash» в зависимости от ваших потребностей.
Только для проверки синтаксиса:
shellcheck [programPath]
Для запуска программы только в том случае, если синтаксис проходит успешно, поэтому отладка как синтаксиса, так и выполнения:
защищенный [programPath]