Проверка перед запуском или в CI
С -S warning замечания уровней info и style не печатаются и не влияют на
код: 1 будет, только если остались warning или error.
shellcheck читает скрипт bash или sh, не выполняя его, и находит ошибки: переменные без кавычек, cd без проверки.
shellcheck backup.sh
проверить скрипт
shellcheck *.sh
несколько файлов сразу
shellcheck -f gcc backup.sh
одно замечание — одна строка
shellcheck -S warning backup.sh
только warning и error
shellcheck -e SC2034 backup.sh
не показывать этот код
shellcheck -x backup.sh
читать файлы из source
shellcheck -s bash lib.sh
файл без shebang — как bash
shellcheck -f diff backup.sh
готовые правки в виде diff
shellcheck — линтер для скриптов bash и sh. Он читает текст
скрипта, ничего не выполняя, и показывает места, где скрипт сломается или
поведёт себя не так, как задумано. Замечание — это строка скрипта, под ней
галочка ^-- на проблемном месте, код SCxxxx, уровень и объяснение:
Часто ниже идёт Did you mean: и исправленная строка. Для cp $f /tmp/
это SC2086 (info): Double quote to prevent globbing and word splitting. и
предложение cp "$f" /tmp/. По коду замечания есть страница с разбором:
https://www.shellcheck.net/wiki/SC2086.
Коды SC1xxx — ошибки разбора текста, SC2xxx — ошибки смысла, SC3xxx —
то, чего нет в POSIX sh.
| Уровень | Что значит |
|---|---|
| error | скрипт не сработает так, как написан |
| warning | почти наверняка ошибка |
| info | сработает, пока не встретит пробел, пустое значение, \ |
| style | можно проще или надёжнее |
Какой оболочкой проверять, shellcheck узнаёт из строки #!: в примере выше
файл начинается с #!/bin/sh, и [[ ]] отмечен — в sh его нет. Код завершения:
0 — замечаний нет, 1 — есть, 2 — файл не прочитан.
| Код | Что не так | Как исправить |
|---|---|---|
| SC2086 | $var без кавычек делится на слова |
"$var" |
| SC2164 | cd без проверки — дальше работа идёт в другом каталоге |
cd /srv/app || exit |
| SC2045 | цикл по выводу ls |
for f in "$dir"/* |
| SC2162 | read без -r портит \ |
read -r line |
| SC2181 | $? вместо проверки самой команды |
if ! cmd; then |
| SC2034 | переменная не используется — часто опечатка в имени | проверь имя |
| SC2115 | rm -rf "$dir/"* при пустой dir удалит /* |
"${dir:?}/"* |
| SC2155 | export x=$(cmd) прячет код cmd |
x=$(cmd), потом export x |
Основные ключи — в таблице ниже. Полный список — man shellcheck.
| Ключ | Что делает | Пример |
|---|---|---|
-f --format tty|gcc|diff|json |
Вид вывода; gcc — одна строка на замечание, diff — готовые правки. | shellcheck -f gcc backup.sh |
-S --severity error|warning|info|style |
Показывать замечания этого уровня и выше. | shellcheck -S warning *.sh |
-e --exclude SC2086,SC2034 |
Не показывать замечания с этими кодами. | shellcheck -e SC2034 backup.sh |
-s --shell bash|sh|dash|ksh |
Какой оболочкой проверять, если в файле нет строки | shellcheck -s bash lib.sh |
-x --external-sources |
Читать файлы, подключённые через source или точку. | shellcheck -x deploy.sh |
# shellcheck disable= SCxxxx |
Комментарий в скрипте — не проверять это в следующей команде. | # shellcheck disable=SC2086 |
-o --enable CHECK|all |
Включить необязательные проверки; список — shellcheck --list-optional. | shellcheck -o all backup.sh |
# shellcheck shell= bash |
Первой строкой файла без | # shellcheck shell=bash |
Ничего не найдено. Попробуй запрос короче.
С -S warning замечания уровней info и style не печатаются и не влияют на
код: 1 будет, только если остались warning или error.
Комментарий действует на следующую команду. Пиши рядом причину: через месяц она будет не очевидна.
Файл .shellcheckrc в каталоге скрипта или выше:
Без -x shellcheck пишет SC1091 … Not following и функции из
подключённого файла не видит.
Готовую правку дают простые замечания: кавычки, || exit.
Читать diff — в diff-patch.
В файле нет строки #!, и shellcheck не знает, какой оболочкой его читать.
Допиши #!/bin/bash или, для подключаемого файла, первой строкой
# shellcheck shell=bash.
Файла по этому пути нет: опечатка в имени или запуск не из того каталога.
shellcheck выходит с кодом 2.
shellcheck не знает замысла: иногда разбиение на слова или переменная из
другого файла нужны намеренно. Отключи замечание комментарием
# shellcheck disable=SCxxxx над строкой и напиши причину.
shellcheck проверяет только текст. Он не знает, есть ли файл, хватит ли
прав, какой PATH у службы и что вернёт команда. Такие ошибки видны при
запуске: проверяй коды и журнал.
Подсказка чинит одно замечание и не видит замысла. В примере выше
for f in $(ls "$src") получил кавычки, но всё ещё перебирает вывод ls —
замечание SC2045 осталось. А кавычки вокруг переменной, которая
намеренно делится на несколько опций (rsync $RSYNC_OPTS), склеят их в
один аргумент — команда сломается. Для набора опций заведи массив:
opts=(-a --delete); rsync "${opts[@]}" src/ dst/.
shellcheck учит проверять.[ ] и [[ ]], где кавычки важнее всего.ls.-f diff.Есть неточность? Сообщить об ошибке в статье