Назад до інструментів

Лінтер Bash-скриптів

Вставте shell-скрипт і знайдіть баги, що проявляються лише на сервері — неекрановані змінні, скрипти #!/bin/sh з bash-специфічним синтаксисом, rm -rf $VAR, незакритий fi. Кожне попередження пояснено простою мовою, з точним рядком і стовпцем.

Вхідні дані

Ваш скрипт

Нічого не завантажується — перевірка виконується в цій вкладці. Вставте весь файл, разом із shebang, щоб працювала перевірка діалекту.

Перевірено рядків: 1.

Результат

Підсумок

Перевірка на основі шаблонів для поширених і важливих помилок bash — це не повноцінна реалізація ShellCheck, і вона не виявить усе. Запустіть через ShellCheck для повного аналізу
Shebang
Shebang не знайдено
Помилки
0
Попередження
1
Примітки
0

Вставте скрипт вище або завантажте приклад, щоб перевірити його.

Застосовано виправлень: 1 (1 × shebang added)

Знахідки

Що зламається і чому

Лише баги коректності — без стильових чи портативних побажань.

СерйозністьРядок:стовпецьПравилоПовідомленняВиправлення
warning1:1WX100

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 $dst
cp "$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 ./cache
cd /srv/app || exit 1 rm -rf ./cache

If 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.txt
sort f.txt > f.tmp && mv f.tmp f.txt

The redirect truncates the file before sort opens it, so you are left with an empty file.

Assignments take no spaces

NAME = value
NAME=value

With 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 *.log

ls output is one string that gets split on whitespace, so filenames with spaces split into pieces.

read needs -r

while read line
while IFS= read -r line

Without -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 та активацією за кілька хвилин.

Переглянути хостинг