Bash — однострочники и скрипты
Приветствую! Здесь вы наверняка найдете, что ищете. Примеры в лаборатории рассчитаны на то, что мы разбираем что-то конкретное.
Текущая статья посвящена готовым bash one liner и shell-скрипты с построчным разбором.
Поэтому за теорией по текущей теме вам — в энциклопедию. Если ещё не погружались, то маршрут прост:
- Основы
- Система и сеть
- Данные и разметка
- Код и разработка
- Языки
- Искусственный интеллект
- Проект
- Инфраструктура и безопасность
- Спин-офф
Обязательно пройдитесь.
А теперь приступим к нашему предмету.
Установка и первый запуск — Первая программа на Bash.
Кавычки, тесты `[[ ]]`, циклы — Синтаксис и Условия и циклы.
Знаки `|`, `>`, `$()` — Терминал, знаки препинания.
Опасные команды из чата — Опасные скрипты.
Основы Bash в терминале
Bash (Bourne Again Shell) — программа, которая читает вашу строку, запускает утилиты (cat, grep, find…) и может выполнять файлы .sh. В Linux и macOS Bash часто стоит по умолчанию; в Windows удобно WSL или Git Bash. Отдельные Unix-утилиты (grep, ls, find…) на Windows можно также поставить нативно через Microsoft Coreutils (Preview) — это не замена bash; см. grep на Windows.
Однострочник — цепочка команд в одной строке, часто через | (pipe): вывод слева становится входом справа.
Скрипт — текстовый файл с командами; первая строка #!/usr/bin/env bash говорит системе, чем его выполнять.
Навигация по примерам
| Ищут в интернете (RU / EN) | Раздел ниже |
|---|---|
| bash read file / bash прочитать файл | cat и less · Построчно |
| bash read file line by line | while read · Скрипт суммы |
| bash count lines / wc -l | wc |
| bash write to file / записать в файл | echo и >> · Here-document |
| bash if file exists | Проверка -f |
| bash for loop / цикл по файлам | for по маске |
| bash script arguments $1 | Аргументы |
| bash grep recursive / найти текст в папке | grep -R |
| bash find files by name | find |
| bash sort uniq / подсчёт повторов | sort | uniq |
| bash backup tar.gz | Архив |
| bash set -euo pipefail | Шаблон скрипта |
| linux shell script example | Стартовые скрипты |
| bash hello world script | Привет, аргумент |
Какую команду выбрать
| Вам нужно… | Откройте пример | Что скопировать |
|---|---|---|
| Быстро посмотреть файл | cat | cat file.txt |
| Большой лог пролистать | less | less app.log |
| Посчитать строки | wc | wc -l file.txt |
| Дописать строку в лог | >> | echo "…" >> log.txt |
| Пройти файл построчно в терминале | while read | цикл while read -r |
| Проверить, есть ли файл | [ -f ] | [[ -f path ]] |
Все .py в папке |
for | for f in ./*.py |
| Найти слово в проекте | grep | grep -RIn "TODO" . |
| Сохранить как скрипт | Шаблон | первые 3 строки + ваш код |
Как запустить за 30 секунд
Однострочник
- Откройте терминал в нужной папке (
cdв каталог с файлами). - Вставьте команду целиком, Enter.
- Смотрите вывод в консоли.
Скрипт
- Создайте
demo.sh, вставьте код (с#!/usr/bin/env bash). - В той же папке:
chmod +x demo.sh
./demo.sh
- Либо без прав на выполнение:
bash demo.sh.
| Среда | Где терминал |
|---|---|
| Ubuntu / Debian | Ctrl+Alt+T |
| macOS | Terminal.app |
| Windows | WSL или Git Bash из меню Пуск; опционально winget install Microsoft.Coreutils для grep/ls/find без bash |
Базовые термины
| Термин | Простыми словами |
|---|---|
| Shell | Оболочка: читает команды и запускает программы |
| Bash | Самый частый shell в учебниках и на серверах |
| Команда | Имя программы + аргументы: wc -l file.txt |
| Пайплайн | cmd1 | cmd2 — stdout первой команды → stdin второй |
| Перенаправление | > перезапись файла, >> дописывание, < ввод из файла |
| Переменная | name="Алиса" · обращение "$name" |
| Код возврата | Число 0 = успех; другое = ошибка (важно для скриптов) |
| Shebang | Первая строка #!/usr/bin/env bash в файле скрипта |
Обязательный шаблон скрипта
Любой учебный или рабочий скрипт, который вы сохраняете в файл, удобно начинать так:
#!/usr/bin/env bash
set -euo pipefail
# ваш код
echo "Готово"
Разбор по строкам.
| Строка | Что происходит | Зачем запомнить |
|---|---|---|
#!/usr/bin/env bash |
env ищет bash в PATH и передаёт ему файл |
Работает в разных дистрибутивах |
set -e |
Выйти при ошибке любой команды | Скрипт останавливается, а не «едет» дальше |
set -u |
Ошибка при $несуществующая |
Ловит опечатки в именах переменных |
set -o pipefail |
Ошибка в a | b, даже если b успешен |
Честный код возврата пайплайна |
echo "Готово" |
Печать в stdout | Видно, что скрипт дошёл до конца |
Что увидите в терминале после ./demo.sh:
Готово
Типичные ошибки.
- Файл сохранён в Windows с окончаниями строк CRLF →
bash\r: No such file. Решение: редактор в режиме LF илиdos2unix demo.sh. - Забыли
chmod +x→Permission denied. Решение:chmod +x demo.shилиbash demo.sh. - Запускаете из другой папки → скрипт не находит
data.txt. Решение:cdв каталог с данными или укажите полный путь.
Полный каркас с trap, getopts и логами — шаблон production.
Стартовые однострочники
Команды, которые чаще всего копируют из поиска на первом занятии по Linux.
Показать файл — cat
Задача. Вывести содержимое маленького текстового файла на экран.
cat notes.txt
Разбор.
| Часть | Смысл |
|---|---|
cat |
Concatenate — «склеить и показать»; для одного файла просто печатает его |
notes.txt |
Путь к файлу относительно текущей папки терминала |
Что увидите (если в notes.txt две строки):
Первая строка
Вторая строка
Смысл приёма. cat — самый короткий способ проверить «что внутри файла» перед обработкой.
Частая ошибка. cat на огромном логе — тысячи строк пролетают мимо. Для больших файлов — less.
Попробуйте сами. echo "тест" > notes.txt затем cat notes.txt.
Пролистать большой файл — less
Задача. Открыть длинный лог и читать по экрану.
less /var/log/syslog
Разбор.
| Клавиша | Действие |
|---|---|
Пробел |
Страница вниз |
b |
Страница вверх |
/ERROR |
Поиск вперёд по слову ERROR |
q |
Выход |
Смысл приёма. less ничего не меняет в файле — только просмотр.
Подсчёт строк — wc
Задача. Узнать, сколько строк в файле (частый вопрос в лабораторной).
wc -l students.txt
Разбор.
| Часть | Смысл |
|---|---|
wc |
Word count — считает строки, слова, байты |
-l |
Только lines (строки) |
вывод 42 students.txt |
42 строки в файле students.txt |
Только число без имени файла:
wc -l < students.txt
Здесь < students.txt подаёт файл на вход wc, поэтому в выводе одно число.
Частая ошибка. Считать строки через cat file | wc -l — работает, но лишний процесс; достаточно wc -l file.
Записать и дописать в файл — echo
Задача. Создать одну строку в новом файле и дописать вторую без удаления первой.
echo "строка 1" > new.txt
echo "строка 2" >> new.txt
cat new.txt
Разбор.
| Оператор | Действие | Аналогия |
|---|---|---|
> |
Перезаписать файл (старое содержимое стирается) | «Новый лист» |
>> |
Дописать в конец | «Добавить в конец тетради» |
echo "текст" |
Печать текста в stdout | |
echo … > file |
Перенаправить stdout в файл |
Что увидите:
строка 1
строка 2
Смысл приёма. Простейшее логирование: каждый запуск скрипта добавляет строку в app.log.
Частая ошибка. Второй раз открыли с > вместо >> — первая запись исчезла.
С датой в лог:
echo "$(date -Iseconds) запуск OK" >> backup.log
| Фрагмент | Смысл |
|---|---|
$(date -Iseconds) |
Подстановка: выполнить date и подставить результат |
-Iseconds |
ISO-формат с секундами |
Несколько строк в файл — here-document
Задача. Создать файл из трёх строк без редактора nano/vim.
cat > config.txt <<'EOF'
host=localhost
port=8080
debug=true
EOF
Разбор.
| Строка | Смысл |
|---|---|
cat > config.txt |
Всё, что «печатает» cat, идёт в config.txt |
<<'EOF' |
Читать строки до строки EOF на отдельной строке |
кавычки в 'EOF' |
Внутри не раскрывать $переменные |
финальный EOF |
Конец ввода, без пробелов перед ним |
Смысл приёма. Удобно в скриптах генерировать маленький конфиг или SQL.
Построчное чтение в однострочнике
Задача. Для каждой строки data.txt напечатать её с префиксом.
while IFS= read -r line; do
printf '>> %s\n' "$line"
done < data.txt
Разбор построчно.
| Фрагмент | Смысл |
|---|---|
while … do … done |
Цикл, пока read возвращает успех |
IFS= read -r line |
Прочитать одну строку; -r — не трогать обратный слэш |
IFS= |
Не обрезать пробелы по краям при чтении (тонкая настройка) |
"$line" |
Кавычки — имя файла с пробелами не разобьёт команду |
< data.txt |
Ввод цикла из файла, а не с клавиатуры |
printf '>> %s\n' |
Форматированный вывод (надёжнее echo для спецсимволов) |
Тестовый data.txt:
alpha
beta
gamma
Вывод:
>> alpha
>> beta
>> gamma
Смысл приёма. Тот же паттерн, что for line in f: в Python — основа для подсчёта, фильтра лога, парсинга CSV без библиотек.
Проверка, что файл существует
Задача. Напечатать «есть» или «нет» для config.json.
if [[ -f config.json ]]; then
echo "файл есть"
else
echo "файла нет"
fi
Разбор.
| Тест | Проверяет |
|---|---|
-f путь |
Обычный файл существует |
-d путь |
Каталог |
-r путь |
Читаем |
-x путь |
Исполняемый |
[[ … ]] |
Условие Bash (пробелы внутри обязательны) |
Однострочник для быстрой проверки:
[[ -f config.json ]] && echo "есть" || echo "нет"
| Часть | Смысл |
|---|---|
&& |
Выполнить справа, только если слева успех (код 0) |
| ` |
Однострочники — поиск, сортировка, файлы
Найти текст в папке — grep
Задача. Показать все строки с словом error в проекте (регистр как в файле).
grep -RIn "error" ./src/
Разбор флагов.
| Флаг | Действие |
|---|---|
-R |
Рекурсивно по каталогам |
-I |
Пропускать бинарники |
-n |
Номер строки |
"error" |
Шаблон поиска (здесь простая подстрока) |
./src/ |
Где искать |
Только имена файлов, где есть совпадение:
grep -Rl "TODO" .
Смысл приёма. Быстрый аудит кода и логов перед экзаменом или релизом.
Сложные шаблоны — Regex — готовые паттерны.
Хвост лога в реальном времени
tail -n 30 -f app.log
| Флаг | Смысл |
|---|---|
-n 30 |
Последние 30 строк |
-f |
Follow — ждать новые строки (как «живой» лог) |
Остановка: Ctrl+C.
Подсчёт повторяющихся строк
Задача. Топ-5 самых частых IP в списке (по одному IP на строку).
sort ips.txt | uniq -c | sort -nr | head -n 5
Разбор пайплайна слева направо.
| Шаг | Команда | Что делает |
|---|---|---|
| 1 | sort ips.txt |
Сортирует строки; одинаковые становятся соседями |
| 2 | uniq -c |
Считает подряд идущие одинаковые |
| 3 | sort -nr |
Сортировка по числу в начале строки, по убыванию |
| 4 | head -n 5 |
Взять первые 5 строк |
Смысл приёма. Классический однострочник аналитики без Python и Excel.
Частая ошибка. uniq без предварительного sort — считает только соседние дубликаты.
Найти файлы по имени — find
Задача. Список всех .py в текущем дереве.
find . -type f -name '*.py'
Разбор.
| Часть | Смысл |
|---|---|
. |
Старт — текущая папка |
-type f |
Только файлы |
-name '*.py' |
Маска имени; кавычки защищают * от shell |
С пробелами в именах (для ls или архивации):
find . -type f -name '*.log' -print0 | xargs -0 ls -lh
| Часть | Смысл |
|---|---|
-print0 |
Пути через символ NUL |
xargs -0 |
Читать аргументы с NUL — безопасно для пробелов |
Стартовые скрипты
Пять файлов, с которых обычно сдают первую лабораторную по shell.
Привет, мир с аргументом
Задача. Скрипт печатает приветствие; имя — первый аргумент или «мир».
#!/usr/bin/env bash
set -euo pipefail
name="${1:-мир}"
echo "Привет, ${name}!"
Разбор.
| Строка | Смысл |
|---|---|
${1:-мир} |
Первый аргумент $1; если пусто — подставить «мир» |
"${name}" |
Кавычки при подстановке — обязательная привычка |
Запуск и вывод:
./hello.sh Алиса
Привет, Алиса!
./hello.sh
Привет, мир!
Попробуйте сами. Добавьте второй аргумент — фамилию — и выведите оба через "$1" и "$2".
Все аргументы командной строки
Задача. Показать, как Bash видит параметры скрипта.
#!/usr/bin/env bash
set -euo pipefail
echo "Имя скрипта (путь): $0"
echo "Количество аргументов: $#"
echo "Все слова одной строкой: $*"
echo "Первый аргумент: ${1:-<нет>}"
Разбор переменных.
| Переменная | Содержимое |
|---|---|
$0 |
Как вызвали скрипт (./demo.sh) |
$# |
Сколько аргументов передано |
$* |
Все аргументы |
$1, $2, … |
По одному |
$@ |
Все аргументы как отдельные слова (в циклах часто лучше $*) |
Запуск:
./args.sh one two three
Вывод (пример):
Имя скрипта (путь): ./args.sh
Количество аргументов: 3
Все слова одной строкой: one two three
Первый аргумент: one
Цикл по файлам в папке
Задача. Для каждого .txt вывести имя и число строк.
#!/usr/bin/env bash
set -euo pipefail
shopt -s nullglob
for path in ./*.txt; do
lines=$(wc -l < "$path")
printf '%s: %s строк\n' "$(basename "$path")" "$lines"
done
Разбор.
| Строка | Смысл |
|---|---|
shopt -s nullglob |
Если нет .txt, цикл не выполнится с буквальной маской *.txt |
for path in ./*.txt |
Перебор файлов по шаблону в текущей папке |
wc -l < "$path" |
Подсчёт строк без имени файла в выводе |
basename "$path" |
Только имя файла без ./ |
Подготовка для проверки:
echo "a" > one.txt
echo -e "b\nc" > two.txt
./count_txt.sh
Ожидаемый вывод:
one.txt: 1 строк
two.txt: 2 строк
Частая ошибка. for f in $(ls *.txt) — ломается на пробелах в имени. Используйте for f in ./*.txt.
Сумма чисел из файла
Задача. В numbers.txt по одному целому на строку — вывести сумму.
#!/usr/bin/env bash
set -euo pipefail
sum=0
while IFS= read -r line || [[ -n "$line" ]]; do
[[ -z "$line" ]] && continue
sum=$((sum + line))
done < numbers.txt
echo "Сумма: $sum"
Разбор.
| Строка | Смысл |
|---|---|
sum=0 |
Инициализация (без пробелов вокруг =) |
read -r line |
Одна строка без интерпретации \ |
| ` | |
[[ -z "$line" ]] && continue |
Пропустить пустые строки |
$((sum + line)) |
Арифметика целых в Bash |
< numbers.txt |
Ввод цикла из файла |
numbers.txt:
10
20
30
Вывод: Сумма: 60
Смысл приёма. Типовая формулировка задания: «прочитать файл и посчитать».
Проверка — файл или каталог
| Конструкция | Смысл |
|---|---|
${1:?текст} |
Нет аргумента — сообщение и выход с ошибкой |
>&2 |
Печать в stderr (поток ошибок) |
exit 1 |
Код «неуспех» для проверяющей системы |
Практические мини-задачи
Формулировки, близкие к школьным и вузовским лабораторным.
8.1. Подсчёт слов в файле
Задача. Вывести число слов в essay.txt.
wc -w < essay.txt
| Флаг | Смысл |
|---|---|
-w |
words — слова |
Скрипт-обёртка:
#!/usr/bin/env bash
set -euo pipefail
file="${1:?укажите файл}"
words=$(wc -w < "$file")
echo "Слов в $file: $words"
8.2. Фильтр строк лога по ERROR
Задача. Из server.log вывести только строки с ERROR.
grep 'ERROR' server.log
Сохранить в новый файл:
grep 'ERROR' server.log > errors-only.log
Разбор: grep читает файл построчно; шаблон — подстрока. В Python тот же смысл — фильтр лога.
Скрипт с подсчётом:
#!/usr/bin/env bash
set -euo pipefail
log="${1:?файл лога}"
count=$(grep -c 'ERROR' "$log" || true)
echo "Строк с ERROR: $count"
|| true — если совпадений 0, grep -c вернёт код 1; с set -e без || true скрипт оборвётся.
8.3. Переименование фото по порядку
#!/usr/bin/env bash
set -euo pipefail
prefix="${1:?нужен префикс, например photo}"
shopt -s nullglob
n=1
for f in *.jpg; do
new="${prefix}_$(printf '%03d' "$n").jpg"
mv -n -- "$f" "$new"
echo "$f -> $new"
n=$((n + 1))
done
| Часть | Смысл |
|---|---|
printf '%03d' "$n" |
001, 002, … |
mv -n |
Не перезаписывать, если цель есть |
-- |
Конец опций mv |
Перед боевым запуском замените mv на echo mv и проверьте список.
8.4. Топ-10 IP в access.log (упрощённо)
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -n 10
| Команда | Роль |
|---|---|
awk '{print $1}' |
Первый столбец строки (здесь считаем, что это IP) |
| остальное | пайплайн sort/uniq |
Реальные логи сложнее — см. Regex или Python.
8.5. Архив папки с датой в имени
#!/usr/bin/env bash
set -euo pipefail
src="${1:?каталог-источник}"
dst="${2:-.}"
stamp="$(date +%Y%m%d_%H%M%S)"
out="${dst}/backup_${stamp}.tar.gz"
tar -czf "$out" -C "$src" .
echo "Создан архив: $out"
| Часть | Смысл |
|---|---|
tar -czf |
Создать gzip-архив |
-C "$src" . |
Упаковать содержимое каталога, пути без лишнего префикса |
date +%Y%m%d_%H%M%S |
Метка времени в имени файла |
Скрипт с функцией log
Задача. Печатать сообщения с временем UTC — привычка для отчётов и серверов.
#!/usr/bin/env bash
set -euo pipefail
log() {
printf '[%s] %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$*"
}
log "старт обработки"
# … ваша работа …
log "готово"
| Строка | Смысл |
|---|---|
log() { … } |
Объявление функции |
"$*" |
Все аргументы вызова log одной строкой |
date -u |
Время в UTC |
Частые вопросы
Чем эта глава отличается от Примеры скриптов в Linux?
Здесь — примеры с разбором по шагам. В 113 — короткий production-минимум: trap, getopts, health-check.
Bash на Windows без Linux?
Установите Git for Windows (Git Bash) или WSL — для скриптов .sh и полноценного bash. Для отдельных команд (grep, ls, find) без подсистемы Linux подойдёт Microsoft Coreutils (Preview): winget install Microsoft.Coreutils. Пути вида /c/Users/… в Git Bash и /mnt/c/… в WSL различаются — запускайте скрипт из той среды, где создавали файлы.
Почему $'\r': command not found?
Файл сохранён с окончаниями Windows (CRLF). Сохраните в UTF-8 LF или выполните dos2unix script.sh.
Как сдать лабораторную?
Архив: скрипт .sh, тестовые input.txt, скриншот терминала с командой и выводом, 2–3 предложения «что делает каждый блок» — можно взять из таблиц разбора выше.
Когда переходить на Python?
Если логика разрослась (JSON, API, тесты) — Python — файлы и текст. Bash остаётся для склейки утилит и CI.
Типичные ошибки — сводка
| Ошибка | Что происходит | Исправление |
|---|---|---|
for f in $(ls) |
Слом на пробелах в имени | for f in ./* |
$var без кавычек |
Разбиение строки | "$var" |
rm -rf $dir/ при пустом $dir |
Опасное удаление | Проверка [[ -n "$dir" ]] · Опасные скрипты |
Забыли set -e |
Скрипт идёт после ошибки | Шаблон в начале файла |
curl | bash из интернета |
Чужой код на вашем ПК | Сначала читать скрипт |
Перед cron: shellcheck script.sh и чек-лист.
Что изучить дальше
| Тема | Куда перейти |
|---|---|
| Синтаксис и циклы | Bash — энциклопедия |
| HTTP из терминала | curl / fetch |
| Порт занят, dev-сервер | CLI — типовые сценарии |
| Git add, commit, push | Git — шпаргалка |
| CI на GitHub | GitHub Actions |
| Сложный текст | Regex |
| Файлы на Python | Python — файлы и текст |
| Production-скрипты | Linux scripts |
Что попробовать самому
- Создайте
numbers.txt, запустите скрипт суммы. - Возьмите любой
.log, выполните топ повторов или grep ERROR. - Перепишите один однострочник в файл
.shс шаблоном. - Сравните свой health-check с curl и production-шаблоном.
В отчёте укажите одну таблицу «команда → смысл» по вашему скрипту. Достаточно 5–7 строк из разборов выше — это показывает, что вы понимаете код, а не только скопировали однострочник из поиска.