Возможно очевидное предостережение: это проверяет синтаксис, но не проверяет, пытается ли ваш bash-скрипт выполнить команду, которой нет в вашем пути, как ech helloвместо echo hello.
На man-странице bash в разделе «КОМАНДЫ / НАСТРОЙКИ ОБОЛОЧКИ ОБЪЕКТА» задокументирована -n, и, как указано в начале man-страницы, bash интерпретирует все доступные односимвольные опции set.
ephemient
24
чтобы добавить к (не для меня) неочевидное предостережение, он также не поймает ошибку, вызванную отсутствием пробела if ["$var" == "string" ]вместоif [ "$var" == "string" ]
Brynjar
11
@Brynjar Это потому, что это просто проверка синтаксиса. Открытая скобка - это не синтаксис, это имя функции, которую нужно запустить. type [говорит "[это встроенная оболочка". В конечном итоге он делегирует testпрограмме, но также ожидает закрывающую скобку. Таким образом if test"$var", это не то, что имел в виду автор, но синтаксически допустимо (скажем, $ var имеет значение «a», тогда мы увидим «bash: testa: команда не найдена»). Дело в том, что синтаксически нет пропущенного места.
Джошуа Чик
2
@JoshuaCheek: [в этом случае встроенный вызов вызывается только в том случае, если он $varрасширяется до пустой строки . Если $varрасширяется до непустой строки, [как сцепляется с этой строкой и интерпретируются как команда имя (не функция имя) на Bash, и, да, то есть синтаксический действительно, но, как вы заявляете, очевидно , не намерена. Если вы используете [[вместо [, даже если [[это ключевое слово оболочки (а не встроенное), вы получите тот же результат, потому что непреднамеренная конкатенация строк по-прежнему отменяет распознавание ключевого слова.
mklement0
2
@JoshuaCheek: Bash еще синтаксис проверяюще здесь: это проверка простой команды вызова синтаксис: ["$var"является синтаксический допустимым именем команды выражения; Точно так же токены ==и "$string"являются действительными аргументами команды . ( Как правило, встроенный [разбираются с командой синтаксисом, тогда [[- как оболочка ключевым слова - анализируются по- разному.) Встроенная команда оболочки [никак не делегирует на « testпрограмму» (внешняя утилита): bash, dash, ksh, zshвсе они имеют встроенные версии как [иtestи они не называют своих внешних утилитарных аналогов.
mklement0
127
Время меняет все. Вот веб-сайт, который обеспечивает онлайн-проверку синтаксиса сценария оболочки.
Я обнаружил, что это очень мощное обнаружение распространенных ошибок.
О ShellCheck
ShellCheck - это инструмент статического анализа и линтинга для скриптов sh / bash. Он в основном сосредоточен на обработке типичных синтаксических ошибок начального и промежуточного уровня и ловушек, когда оболочка просто дает загадочное сообщение об ошибке или странном поведении, но также сообщает о нескольких более сложных проблемах, где угловые случаи могут привести к задержке сбоев.
Отличный совет; на OSX теперь вы можете также установить shellcheck.net CLI, shellcheckчерез Homebrew : brew install shellcheck.
mklement0
3
Также на debian & friends:apt-get install shellcheck
тот другой парень
Для Ubuntu trusty этот пакет должен быть установлен с trusty-backports.
Петерино
Как упоминалось выше, нужна надежная зависимость, и вы можете установить ее, как показано ниже в ubuntu 14.04: sudo apt-get -f install, затем: sudo sudo apt-get install shellcheck
zhihong
Это действительно полезно, но он использует не парсер Bash, а свой собственный. В большинстве случаев это достаточно хорошо и может идентифицировать как синтаксический анализ, так и другие проблемы, но есть по крайней мере один крайний случай (и, вероятно, другие, которые я не видел), где он не анализируется совершенно одинаково.
Даниэль Х
38
Я также включаю опцию 'u' в каждом скрипте bash, который я пишу, чтобы выполнить дополнительную проверку:
set-u
Это сообщит об использовании неинициализированных переменных, как в следующем скрипте 'check_init.sh'
я всегда устанавливаю эти флаги в моих скриптах bash, если они проходят, хорошо бы перейти "set -o errexit" "set -o nounset" "set -o pipefail"
μολὼν.λαβέ
+1, set -uхотя это на самом деле не отвечает на вопрос, потому что вы должны запустить скрипт, чтобы получить сообщение об ошибке. Даже не bash -n check_init.shпоказывает, что предупреждение
rubo77
23
sh -n script-name
Запустите это. Если в скрипте есть какие-либо синтаксические ошибки, он возвращает то же сообщение об ошибке. Если ошибок нет, то выходит без сообщения. Вы можете проверить сразу с помощью echo $?, который вернет 0подтверждение успешной без каких-либо ошибок.
У меня это хорошо сработало. Я работал на ОС Linux, Bash Shell.
Хотя это не совсем относится к проверке синтаксиса bash - использование set -x и set + x для отладки полного скрипта или его частей довольно полезно
GuruM
Спасибо за это, я не знал, не знал о -n, но я хотел, чтобы @GuruM> sh -x test.sh отображал сгенерированный вывод сценария
zzapper
1
Да. Я забыл упомянуть, что вы можете сделать следующее В командной строке: 1) bash -x test.sh # Это запускает весь скрипт в «режиме отладки» 2) set + x; bash test.sh; установить -x #set режим отладки вкл / выкл до / после запуска скрипта В скрипте: a) #! / bin / bash -x #add 'режим отладки' в верхней части скрипта b) set + x; код; установить -x #add 'режим отладки' для любого раздела скрипта
GuruM
sh -nвероятно, не будет проверять, что скрипт является действительным сценарием Bash. Это может дать ложные негативы. shкакой-то вариант оболочки Bourne, обычно не Bash. Например в Ubuntu Linux realpath -e $(command -v sh)выдает / bin / dash
jarno
4
Я на самом деле проверяю все скрипты bash в текущем каталоге на наличие синтаксических ошибок БЕЗ запуска их с помощью findинструмента:
Пример:
find . -name '*.sh' -exec bash -n {} \;
Если вы хотите использовать его для одного файла, просто отредактируйте шаблон с именем файла.
Но это не сработает, если ваши файлы не заканчиваются .shили не имеют другого расширения, связанного со скриптами Bash, что имеет место, если вы генерируете скрипты, используя какой-либо шаблонизатор, такой как ERB (тогда они заканчиваются .erb). Пожалуйста, проголосуйте за youtrack.jetbrains.com/issue/IDEA-79574, если хотите, чтобы это было исправлено!
Грег Дубицки
1
Если вам требуется в переменной допустимость всех файлов в каталоге (git pre-commit hook, build lint script), вы можете получить вывод stderr команд "sh -n" или "bash -n" (см. Другие ответы) в переменной, и иметь «если / еще» на основе этого
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» в зависимости от ваших потребностей
Ответы:
Возможно очевидное предостережение: это проверяет синтаксис, но не проверяет, пытается ли ваш bash-скрипт выполнить команду, которой нет в вашем пути, как
ech hello
вместоecho hello
.источник
set
.if ["$var" == "string" ]
вместоif [ "$var" == "string" ]
type [
говорит "[это встроенная оболочка". В конечном итоге он делегируетtest
программе, но также ожидает закрывающую скобку. Таким образомif test"$var"
, это не то, что имел в виду автор, но синтаксически допустимо (скажем, $ var имеет значение «a», тогда мы увидим «bash: testa: команда не найдена»). Дело в том, что синтаксически нет пропущенного места.[
в этом случае встроенный вызов вызывается только в том случае, если он$var
расширяется до пустой строки . Если$var
расширяется до непустой строки,[
как сцепляется с этой строкой и интерпретируются как команда имя (не функция имя) на Bash, и, да, то есть синтаксический действительно, но, как вы заявляете, очевидно , не намерена. Если вы используете[[
вместо[
, даже если[[
это ключевое слово оболочки (а не встроенное), вы получите тот же результат, потому что непреднамеренная конкатенация строк по-прежнему отменяет распознавание ключевого слова.["$var"
является синтаксический допустимым именем команды выражения; Точно так же токены==
и"$string"
являются действительными аргументами команды . ( Как правило, встроенный[
разбираются с командой синтаксисом, тогда[[
- как оболочка ключевым слова - анализируются по- разному.) Встроенная команда оболочки[
никак не делегирует на «test
программу» (внешняя утилита):bash
,dash
,ksh
,zsh
все они имеют встроенные версии как[
иtest
и они не называют своих внешних утилитарных аналогов.Время меняет все. Вот веб-сайт, который обеспечивает онлайн-проверку синтаксиса сценария оболочки.
Я обнаружил, что это очень мощное обнаружение распространенных ошибок.
О ShellCheck
ShellCheck - это инструмент статического анализа и линтинга для скриптов sh / bash. Он в основном сосредоточен на обработке типичных синтаксических ошибок начального и промежуточного уровня и ловушек, когда оболочка просто дает загадочное сообщение об ошибке или странном поведении, но также сообщает о нескольких более сложных проблемах, где угловые случаи могут привести к задержке сбоев.
Исходный код на Haskell доступен на GitHub!
источник
shellcheck
через Homebrew :brew install shellcheck
.apt-get install shellcheck
trusty-backports
.Я также включаю опцию 'u' в каждом скрипте bash, который я пишу, чтобы выполнить дополнительную проверку:
Это сообщит об использовании неинициализированных переменных, как в следующем скрипте 'check_init.sh'
Запуск скрипта:
Сообщит следующее:
Очень полезно ловить опечатки
источник
set -u
хотя это на самом деле не отвечает на вопрос, потому что вы должны запустить скрипт, чтобы получить сообщение об ошибке. Даже неbash -n check_init.sh
показывает, что предупреждениеЗапустите это. Если в скрипте есть какие-либо синтаксические ошибки, он возвращает то же сообщение об ошибке. Если ошибок нет, то выходит без сообщения. Вы можете проверить сразу с помощью
echo $?
, который вернет0
подтверждение успешной без каких-либо ошибок.У меня это хорошо сработало. Я работал на ОС Linux, Bash Shell.
источник
sh -n
вероятно, не будет проверять, что скрипт является действительным сценарием Bash. Это может дать ложные негативы.sh
какой-то вариант оболочки Bourne, обычно не Bash. Например в Ubuntu Linuxrealpath -e $(command -v sh)
выдает / bin / dashЯ на самом деле проверяю все скрипты bash в текущем каталоге на наличие синтаксических ошибок БЕЗ запуска их с помощью
find
инструмента:Пример:
find . -name '*.sh' -exec bash -n {} \;
Если вы хотите использовать его для одного файла, просто отредактируйте шаблон с именем файла.
источник
Пустая команда [двоеточие] также полезна при отладке, чтобы увидеть значение переменной
источник
set -x
показывает каждую строку перед ее выполнениемСуществует BashSupport плагин для IntelliJ IDEA , который проверяет синтаксис.
источник
.sh
или не имеют другого расширения, связанного со скриптами Bash, что имеет место, если вы генерируете скрипты, используя какой-либо шаблонизатор, такой как ERB (тогда они заканчиваются.erb
). Пожалуйста, проголосуйте за youtrack.jetbrains.com/issue/IDEA-79574, если хотите, чтобы это было исправлено!Если вам требуется в переменной допустимость всех файлов в каталоге (git pre-commit hook, build lint script), вы можете получить вывод stderr команд "sh -n" или "bash -n" (см. Другие ответы) в переменной, и иметь «если / еще» на основе этого
Замените «sh» на «bash» в зависимости от ваших потребностей
источник