Перейти к основному содержимому

Bash — итоги

Разработчику Аналитику Тестировщику Архитектору Инженеру

Кратко — что стоит унести из раздела "Bash". Если пункт кажется туманным — откройте указанную главу или оглавление.


FAQ — Часто задаваемые вопросы

Типичные сбои и ситуации, с которыми сталкиваются новички после раздела, плюс формулировки, которые часто вводят в поиске ("как написать bash-скрипт", "chmod +x", "bash if else"). Здесь — краткий ответ и ссылка на главу; определения для зачёта — в чек-листе.

Вопрос. В терминале bash или ./script.sh — "command not found", хотя файл на диске есть.

Ответ. На Windows нужен Git Bash или WSL, а не cmd.exe. Для скрипта без ./ каталог должен быть в PATH, иначе оболочка ищет команду в стандартных путях. Проверьте which bash и shebang. Подробнее здесь — первая программа, основы.

Вопрос. Запускаю скрипт — Permission denied, хотя файл создан в редакторе.

Ответ. Нужен флаг исполнения: chmod +x script.sh и запуск ./script.sh. Без +x оболочка не считает файл программой. Подробнее здесь — первая программа.

Вопрос. Ошибка bad interpreter: /usr/bin/env^M или bash\r.

Ответ. Файл сохранён с окончаниями строк Windows (CRLF). Пересохраните в LF (dos2unix, настройка редактора "LF only") и проверьте shebang #!/usr/bin/env bash. Подробнее здесь — первая программа, синтаксис.

Вопрос. Путь с пробелами ломает скрипт — вместо одного файла получается несколько аргументов.

Ответ. Подставляйте переменные и пути в двойных кавычках: "$path", "$@" для всех аргументов. Без кавычек срабатывает word splitting. Подробнее здесь — переменные, синтаксис.

Вопрос. echo $* и echo "$@" ведут себя по-разному — какой вариант в функции?

Ответ. Для передачи всех аргументов вызываемой команде используйте "$@" (каждый аргумент отдельно). $* склеивает аргументы в одну строку. Подробнее здесь — переменные, функции.

Вопрос. syntax error near unexpected token на elif или fi — код "как в примере".

Ответ. Часто скрипт запускают через sh script.sh, а пишут для Bash ([[ ]], массивы). Запускайте bash script.sh или shebang #!/bin/bash. Проверьте парность if/fi, do/done. Подробнее здесь — условия и циклы, ключевые слова.

Вопрос. [ $x = $y ] падает с "unary operator expected" при пустой переменной.

Ответ. Классический [ ломается на пустых значениях. В Bash надёжнее [[ ... ]] и кавычки: [[ "$x" == "$y" ]]. Подробнее здесь — условия и циклы, синтаксис.

Вопрос. Включил set -u — скрипт падает на "нормальной" необязательной переменной.

Ответ. set -u трактует неинициализированные переменные как ошибку. Задайте значение по умолчанию: ${VAR:-} или ${VAR:-default}. Подробнее здесь — обработка ошибок, переменные.

Вопрос. set -e включён, но скрипт не останавливается после ошибки в конвейере.

Ответ. По умолчанию -e смотрит только код последней команды в pipe. Добавьте set -o pipefail и проверяйте $? там, где критично. Подробнее здесь — обработка ошибок.

Вопрос. while read line; do ... done < file в конвейере с cat — счётчик в цикле не растёт.

Ответ. Конвейер может выполняться в подоболочке — переменные снаружи не меняются. Читайте файл через перенаправление < file или process substitution. Подробнее здесь — условия и циклы, файлы и процессы.

Вопрос. Шаблон *.log не находит файлы — скрипт пишет, что совпадений нет.

Ответ. При несовпадении glob Bash может оставить буквальную строку *.log. Включите shopt -s nullglob или проверьте каталог и расширение. Glob в кавычках не раскрывается. Подробнее здесь — синтаксис, файлы.

Вопрос. Внутри одинарных кавычек '$HOME' переменная не подставляется — это баг?

Ответ. В одинарных кавычках нет подстановки — всё буквально. Для переменных — двойные кавычки; для regex и awk часто удобны одинарные. Подробнее здесь — синтаксис, переменные.

Вопрос. Случайно выполнил rm -rf не в той папке — как не повторить?

Ответ. Перед массовым удалением — pwd, ls, алиас rm -i, отказ от rm -rf / и путей с подстановкой без проверки. В WSL путь /mnt/c/... — реальный диск Windows. Подробнее здесь — Опасные скрипты, файлы.

Вопрос. Коллега прислал установку curl https://... | bash — можно запускать?

Ответ. Вы выполняете чужой код с правами вашего пользователя. Сначала скачайте скрипт, прочитайте, запускайте без pipe или в песочнице. Подробнее здесь — Опасные скрипты, экосистема.

Вопрос. Скрипт отлично работает в терминале, в cron — "команда не найдена".

Ответ. У cron урезанный PATH и нет вашего .bashrc. Укажите полные пути (/usr/bin/find), shebang и при необходимости PATH= в crontab. Подробнее здесь — файлы и процессы, экосистема.

Вопрос. export VAR=value в скрипте — дочерний процесс переменную не видит.

Ответ. export действует на дочерние процессы, не на родительский shell после завершения скрипта. Для постоянных значений — файл профиля или systemd environment. Подробнее здесь — переменные, файлы.

Вопрос. Проверяю $? после нескольких команд — "успех", хотя первая упала.

Ответ. $? хранит код последней команды. Сохраняйте сразу: cmd1; ec1=$?; cmd2 или используйте set -e и pipefail. Подробнее здесь — обработка ошибок.

Вопрос. find . -name "*.tmp" -delete удалил больше, чем ожидал.

Ответ. Сначала прогон без -delete: find ... -print. Ограничьте глубину -maxdepth, проверьте точку старта .. Подробнее здесь — файлы, утилиты.

Вопрос. На macOS скрипт с mapfile или readarray падает — на Linux работал.

Ответ. Системный Bash на macOS долго был 3.2. Установите Bash 5 через Homebrew и shebang /opt/homebrew/bin/bash или пишите совместимо с 3.2. Подробнее здесь — история, основы.

Вопрос. В WSL удалил "папку Linux" через Проводник Windows — пропали файлы проекта.

Ответ. Храните проекты в файловой системе WSL (~/...), а не только на /mnt/c/. Кросс-доступ Windows/Linux для критичных данных рискован. Подробнее здесь — первая программа, Опасные скрипты.

Вопрос. Нужны дробные вычисления в скрипте — echo $((1/3)) даёт 0.

Ответ. $(( ))целая арифметика. Для float используйте bc, awk или внешний язык. Подробнее здесь — синтаксис, утилиты.

Вопрос. Фоновая задача command & — терминал закрыли, процесс исчез.

Ответ. Сессия терминала посылает SIGHUP. Используйте nohup, disown или systemd unit для долгих задач. Подробнее здесь — файлы и процессы, справочник.

Вопрос. sudo ./backup.sh — скрипт не видит мои переменные окружения.

Ответ. sudo по умолчанию сбрасывает окружение (env_reset). Передавайте нужное через sudo VAR=value или конфигурацию secure_path, не храните секреты в export. Подробнее здесь — переменные, экосистема.

Вопрос. JSON из API "ломается" в grep — вместо полей каша из скобок.

Ответ. Для JSON используйте jq, а не разбор текста regex. Связывайте curl -s ... | jq '.field'. Подробнее здесь — утилиты, простые приложения.

Вопрос. Функция в скрипте объявлена, но при вызове "command not found".

Ответ. Функцию нужно объявить до вызова (или использовать отдельный файл с source). В subshell ( ) функции родителя недоступны. Подробнее здесь — функции, встроенные команды.

Вопрос. Логи пишутся, но tail -f в скрипте "зависает" и дальше код не идёт.

Ответ. tail -fблокирующая команда. Запускайте в фоне, используйте таймаут или отдельный процесс мониторинга. Подробнее здесь — файлы и процессы, утилиты.

Вопрос. Не знаю, с чего повторить раздел после курса — сразу Kubernetes или Ansible?

Ответ. Закрепите цепочку shebang → кавычки → $? → pipefail на первой программе и обработке ошибок, затем один сценарий из утилит. Инфраструктурные инструменты опираются на уверенный Bash на сервере. Подробнее здесь — оглавление, Терминал.

Вопрос. Чем Bash отличается от sh и что запускает #!/bin/sh?

Ответ. sh — POSIX-оболочка с ограниченным синтаксисом; Bash расширяет sh (массивы, [[ ]], подстановки). Скрипт с #!/bin/sh может упасть на bash-конструкциях. Для переносимости пишите под POSIX или явно укажите bash. Подробнее здесь — история оболочек, основы.

Вопрос. Как написать bash-скрипт с нуля — пошагово для новичка?

Ответ. Создайте файл .sh, добавьте #!/usr/bin/env bash, chmod +x, первая команда echo, запуск ./script.sh. Дальше — переменные, if и цикл. Подробнее здесь — первая программа.

Вопрос. Что такое shebang #! в первой строке скрипта?

Ответ. Shebang говорит ядру, какой интерпретатор запустить для файла. Рекомендуемая форма — #!/usr/bin/env bash (ищет bash в PATH). Подробнее здесь — первая программа, синтаксис.

Вопрос. Как сделать файл исполняемым в Linux — chmod какое число?

Ответ. Для запуска владельцем: chmod +x script.sh или chmod 755 script.sh. Без бита x запуск только через bash script.sh. Подробнее здесь — первая программа, файлы.

Вопрос. Bash — как передать аргументы в скрипт и прочитать $1 $2?

Ответ. Позиционные параметры: $1, $2, все аргументы — "$@". Имя скрипта — $0. Подробнее здесь — переменные, функции.

Вопрос. Как в bash сделать if else — сравнение строк и чисел?

Ответ. Строки и числа в [[ ... ]]: -eq, -ne, ==, -f для файла. Классический [ требует кавычек. Подробнее здесь — условия и циклы, ключевые слова.

Вопрос. Цикл for по файлам в папке — for f in *.txt правильно?

Ответ. Да, for f in *.txt; do ... done — типичный обход glob. При пробелах в именах используйте find ... -print0 | while IFS= read -r -d '' f. Подробнее здесь — условия и циклы, файлы.

Вопрос. Как читать файл построчно в bash — while read line?

Ответ. while IFS= read -r line; do ... done < file — стандартный шаблон; -r не интерпретирует обратный слэш. Подробнее здесь — условия и циклы, файлы.

Вопрос. Перенаправление вывода в bash — >, >>, 2>&1 что значит?

Ответ. > — перезапись stdout, >> — дописать, 2> — stderr, 2>&1 — stderr в stdout. Подробнее здесь — синтаксис, справочник, Терминал.

Вопрос. Конвейер pipe | в Linux — как связать команды?

Ответ. stdout слева идёт в stdin справа: cat log | grep ERROR | wc -l. Код возврата конвейера — с pipefail. Подробнее здесь — основы, обработка ошибок, утилиты.

Вопрос. Как проверить существует ли файл в bash скрипте?

Ответ. Тесты [[ -f "$path" ]] (файл), -d (каталог), -e (существует). Или test -f. Подробнее здесь — условия, файлы.

Вопрос. Bash — как получить текущую дату и время в переменную?

Ответ. date +"%Y-%m-%d_%H-%M-%S" в подстановке: backup_$(date +%F).tar.gz. Подробнее здесь — переменные, утилиты.

Вопрос. Переменные окружения в bash — export PATH как работает?

Ответ. export VAR=value передаёт переменную дочерним процессам. PATH — список каталогов поиска команд. Подробнее здесь — переменные, встроенные команды.

Вопрос. Функция в bash — как объявить и вернуть значение?

Ответ. myfunc() { ...; }, возврат кода — return N, "результат" часто через echo и $(myfunc). Локальные переменные — local. Подробнее здесь — функции.

Вопрос. Массив в bash — как объявить и обойти элементы?

Ответ. arr=(a b c), ${arr[0]}, "${arr[@]}" для всех элементов. Подробнее здесь — переменные, ключевые слова.

Вопрос. case в bash — аналог switch для нескольких веток?

Ответ. Да, case "$var" in pattern) ... ;; esac удобен для флагов и имён команд. Подробнее здесь — условия и циклы, синтаксис.

Вопрос. grep в bash — поиск текста в файле и рекурсивно в папке?

Ответ. grep -r "текст" . — рекурсия; для скорости на больших деревьях — rg. Подробнее здесь — утилиты, справочник.

Вопрос. find — найти файлы по имени и удалить старше N дней?

Ответ. find . -name "*.log" -mtime +30; удаление только после проверки списка. Подробнее здесь — файлы, утилиты.

Вопрос. sed и awk в однострочнике — когда что использовать?

Ответ. sed — замена по шаблону в потоке; awk — колонки и простые отчёты. Для JSON — jq. Подробнее здесь — утилиты, простые приложения.

Вопрос. curl скачать файл в bash — как сохранить на диск?

Ответ. curl -fsSL -o file.zip "https://..."-f падает на HTTP-ошибке, -L следует редиректам. Не pipe в bash без чтения скрипта. Подробнее здесь — утилиты, Опасные скрипты.

Вопрос. Git Bash на Windows — это полноценный bash для обучения?

Ответ. Да, для скриптов и утилит Unix на Windows — удобный старт; пути Windows — /c/Users/.... Для "настоящего" Linux — WSL. Подробнее здесь — первая программа, экосистема.

Вопрос. WSL bash — чем отличается от Git Bash?

Ответ. WSL — ядро Linux в Windows, нативные пакеты apt; Git Bash — эмуляция слоя для git и скриптов. Подробнее здесь — первая программа, оглавление.

Вопрос. Bash или Python для автоматизации — что выбрать?

Ответ. Bash — склейка CLI, деплой, cron на сервере; Python — сложная логика, API, тесты. Часто bash вызывает python. Подробнее здесь — экосистема, Python — о разделе.

Вопрос. set -euo pipefail в начале скрипта — зачем так пишут?

Ответ. -e — выход при ошибке, -u — пустые переменные, pipefail — ошибка в середине pipe. Стандарт для "строгих" скриптов. Подробнее здесь — обработка ошибок, рекомендации в intro.

Вопрос. Как отладить bash-скрипт — пошагово увидеть команды?

Ответ. Запуск bash -x script.sh печатает каждую команду; внутри скрипта set -x / set +x. Подробнее здесь — обработка ошибок, основы.

Вопрос. Cron — как запустить bash-скрипт по расписанию?

Ответ. В crontab укажите полный путь к bash и скрипту, рабочий каталог и PATH. Логи перенаправляйте в файл. Подробнее здесь — файлы и процессы, экосистема.

Вопрос. SSH выполнить команду на удалённом сервере одной строкой bash?

Ответ. ssh user@host 'команда' — кавычки на стороне клиента; для скриптов — копирование scp и запуск. Подробнее здесь — утилиты, Терминал.


Что запомнить

Bash — стандартная оболочка для склейки утилит Unix, CI/CD, деплоя и администрирования Linux-серверов. Сила — в конвейерах, перенаправлении и быстрых однострочниках; слабость — в сложной бизнес-логике и больших кодовых базах.

Основные опоры раздела:

  • Shebang и права#!/usr/bin/env bash, chmod +x, LF без ^M;
  • Кавычки и аргументы"$var", "$@", осознанный glob;
  • Надёжностьset -euo pipefail, явная проверка $?, осмысленные сообщения в stderr;
  • Безопасность — не запускать непрочитанный curl | bash, осторожность с rm, sudo и путями WSL;
  • Инструментыfind, grep, jq, ssh в связке со скриптом (утилиты, справочник).

Три привычки, которые окупаются быстрее всего:

  1. Любой скрипт сначала запускать вручную на копии данных, не на проде.
  2. Ошибку читать целиком (строка, номер, команда), затем открывать главу по теме.
  3. Для переносимости помнить разницу Bash vs sh и версию Bash на macOS.

Куда идти дальше

ТемаРаздел
Терминал и оболочки2.05 Терминал
PowerShellPowerShell — о разделе
Безопасность скриптовОпасные скрипты

Проверьте себя: Чек-лист самопроверки.


См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").