Лінтер Bash-скриптів
Вставте shell-скрипт і знайдіть баги, що проявляються лише на сервері — неекрановані змінні, скрипти #!/bin/sh з bash-специфічним синтаксисом, rm -rf $VAR, незакритий fi. Кожне попередження пояснено простою мовою, з точним рядком і стовпцем.
Вхідні дані
Ваш скрипт
Нічого не завантажується — перевірка виконується в цій вкладці. Вставте весь файл, разом із shebang, щоб працювала перевірка діалекту.
Перевірено рядків: 1.
Результат
Підсумок
Вставте скрипт вище або завантажте приклад, щоб перевірити його.
Застосовано виправлень: 1 (1 × shebang added)
Знахідки
Що зламається і чому
Лише баги коректності — без стильових чи портативних побажань.
| Серйозність | Рядок:стовпець | Правило | Повідомлення | Виправлення |
|---|---|---|---|---|
| warning | 1:1 | WX100 | No shebang line Without a #! line, what runs the script depends entirely on how it is invoked. "./script.sh" hands it to whatever the kernel falls back to, cron runs it under /bin/sh, and your interactive test under bash works fine — so it passes locally and fails as a cron job. | Add as the very first line: #!/usr/bin/env bash |
Довідник
Шпаргалка типових помилок
Баги, які шукає цей лінтер, і як виглядає виправлення. Це ті помилки, що переживають локальне тестування й ламаються у продакшені.
Always quote expansions
cp $src $dstcp "$src" "$dst"Unquoted, the value is split on whitespace and then glob-expanded. One path with a space becomes two arguments.
"$@", never $@
mycmd $@mycmd "$@""$@" is the only form that passes every argument through exactly as received, including empty ones.
[[ ]] is bash, [ ] is POSIX
#!/bin/sh … [[ -f $f ]]#!/bin/sh … [ -f "$f" ]On Debian and Ubuntu /bin/sh is dash. [[ does not exist there — "[[: not found" and the test is false.
Strings with =, numbers with -eq
[ "$n" = 10 ][ "$n" -eq 10 ]= compares text, so "010" ≠ "10". -eq compares integers and errors loudly on non-numeric input.
cd can fail
cd /srv/app
rm -rf ./cachecd /srv/app || exit 1
rm -rf ./cacheIf cd fails the script continues in the previous directory — and the next relative command hits the wrong tree.
Guard rm against an empty variable
rm -rf $DIR/rm -rf "${DIR:?DIR is not set}"/An unset $DIR makes this "rm -rf /". ${VAR:?msg} aborts instead of expanding to nothing.
Never read and write one file
sort f.txt > f.txtsort f.txt > f.tmp && mv f.tmp f.txtThe redirect truncates the file before sort opens it, so you are left with an empty file.
Assignments take no spaces
NAME = valueNAME=valueWith spaces the shell runs NAME as a command. The variable is never set and every later $NAME is empty.
Glob the directory, do not parse ls
for f in $(ls *.log)for f in *.logls output is one string that gets split on whitespace, so filenames with spaces split into pieces.
read needs -r
while read linewhile IFS= read -r lineWithout -r, backslashes are eaten. Without IFS=, leading and trailing whitespace is stripped.
$? is only the last command
mycmd
echo done
[ $? -ne 0 ]if ! mycmd; then …The echo resets $?. Test the command directly rather than inspecting the status later.
Fail fast, fail loudly
#!/bin/bash#!/bin/bash
set -euo pipefail-e stops on the first failure, -u catches typoed variable names, pipefail makes a broken pipeline fail.
Керуєте власним ігровим сервером?
Ігрові сервери Wespner із захистом від DDoS, дисками NVMe та активацією за кілька хвилин.