Урок 8 из 8 · 25 мин · обновлено
Первый скрипт на bash
Как записать команды в файл и запускать их одной командой: строка #!/bin/bash, переменные, подстановка команд, аргументы, условия и циклы. Пишем скрипты для резервной копии и отчёта по логу.
Скрипт — команды в файле
Если одни и те же команды приходится набирать снова и снова, их записывают в файл — скрипт — и запускают одной командой. Сделаем резервную копию учебной папки:
#!/bin/bash
# Резервная копия папки practice с датой в имени архива
today=$(date +%Y-%m-%d)
mkdir -p ~/backups
tar -czf ~/backups/practice-$today.tar.gz -C ~ practice && echo "Готово: practice-$today.tar.gz"
Сохраните это в файл ~/backup.sh любым редактором. В терминале проще всего nano backup.sh: вставьте текст, сохраните Ctrl+O и Enter, выйдите Ctrl+X. Затем:
chmod +x backup.sh
./backup.sh
Готово: practice-2026-10-21.tar.gz
#!/bin/bash— первая строка: каким интерпретатором выполнять файл;- строки с
#дальше — комментарии; tar -czf архив -C ~ practice— упаковать папкуpracticeиз домашней папки в сжатый архив;chmod +x— разрешить запуск, как в уроке 6.
Переменные и подстановка
name="Анна"
echo "Привет, $name"
echo 'Привет, $name'
Привет, Анна
Привет, $name
- переменную создают как
имя=значение, без пробелов вокруг=. С пробелами bash решит, чтоname— это команда; - значение берут через
$имя; - в двойных кавычках переменные подставляются, в одинарных — нет, текст выводится как есть.
$(команда) подставляет результат команды. В скрипте выше today=$(date +%Y-%m-%d) сохраняет сегодняшнюю дату, и она попадает в имя архива.
&& между командами значит: выполни вторую, только если первая прошла успешно. Без него скрипт написал бы «Готово», даже если tar не смог создать архив.
Аргументы и условия
Скрипту можно передавать аргументы, как обычной команде. Внутри первый аргумент — $1, второй — $2. Напишем errors.sh, который считает ошибки в любом логе:
#!/bin/bash
# Считает ошибки в логе, имя файла — первый аргумент
file=$1
if [ ! -f "$file" ]; then
echo "Нет такого файла: $file"
exit 1
fi
echo "Ошибок в $file: $(grep -c ERROR "$file")"
./errors.sh app.log
./errors.sh nope.log
Ошибок в app.log: 3
Нет такого файла: nope.log
if [ условие ]; then … fi— условие. Пробелы внутри квадратных скобок обязательны;-f "$file"— файл существует,!— отрицание: «если файла нет»;exit 1— завершить скрипт с ошибкой. Код 0 значит «успех», любой другой — «что-то пошло не так»;- переменные с именами файлов берут в кавычки
"$file", чтобы не сломаться на именах с пробелами.
Циклы
for повторяет команды для каждого элемента:
for f in photos/jpg/*.jpg; do
echo "Файл: $f"
done
Файл: photos/jpg/cat.jpg
Файл: photos/jpg/dog.jpg
Так переименовывают сотни файлов, обрабатывают каждую строку списка или проверяют несколько серверов подряд. Хороший следующий шаг — запускать скрипты по расписанию: в Linux для этого есть cron.
Попробуйте сами. Напишите скрипт add-date.sh, который добавляет к имени каждого файла .jpg в указанной папке сегодняшнюю дату: cat.jpg → 2026-10-21-cat.jpg. Папку передайте аргументом. Если папки нет, скрипт сообщает об этом и завершается.
Решение
#!/bin/bash
# Добавляет дату в начало имени каждого .jpg в папке
dir=$1
today=$(date +%Y-%m-%d)
if [ ! -d "$dir" ]; then
echo "Нет такой папки: $dir"
exit 1
fi
for f in "$dir"/*.jpg; do
name=$(basename "$f")
mv "$f" "$dir/$today-$name"
echo "$name → $today-$name"
done
chmod +x add-date.sh
./add-date.sh photos/jpg
cat.jpg → 2026-10-21-cat.jpg
dog.jpg → 2026-10-21-dog.jpg
-d проверяет, что это папка. basename отрезает путь и оставляет только имя файла. Переименовываем через mv, как в уроке 3.
Перед запуском таких скриптов на важных файлах сначала замените mv на echo mv — скрипт покажет, что сделает, ничего не трогая.
Мини-тест: проверьте себя
Закрепите урок: несколько вопросов, разбор ответов — в конце.
-
Зачем в первой строке скрипта пишут #!/bin/bash?
Строка с #! говорит системе: выполни этот файл с помощью bash. Без неё скрипт может запуститься другой оболочкой.
-
Почему запись name = "Анна" не создаёт переменную?
С пробелами bash решит, что name — это команда, а = и "Анна" — её аргументы, и выдаст ошибку.
-
Что выведет echo "Ошибок: $(grep -c ERROR app.log)", если в логе 3 ошибки?
$(…) выполняет команду и подставляет её результат прямо в строку.
-
Что делает запись tar … && echo "Готово"?
&& — «и затем, если успешно». Так скрипт не сообщит об успехе, когда архив не создался.