Командная строка Bash [103.1]

Рейтинг: 64.6% · 7 голосов
Полный курс LPIC-1 (экзамены 101-500 и 102-500): архитектура, загрузка, пакеты, команды и текст, ФС и права, шелл-скрипты, пользователи, сервисы, сеть, безопасность. Debian и RHEL.
Ответить
Аватара пользователя
Sergey_Sysadmin
Сообщения: 134
Зарегистрирован: 11 май 2026, 05:31

Командная строка Bash [103.1]

Сообщение Sergey_Sysadmin »

Оглавление курса (41)
  1. Введение в LPIC-1 и как устроен путь администратора
  2. Железо, устройства и модули ядра [101.1]
  3. Загрузка системы: от BIOS до systemd [101.2]
  4. systemd, цели и уровни выполнения [101.3]
  5. План разметки диска и swap [102.1]
  6. Загрузчик GRUB 2 [102.2]
  7. Разделяемые библиотеки [102.3]
  8. Управление пакетами в Debian: dpkg и apt [102.4]
  9. Управление пакетами RPM, DNF и Zypper [102.5]
  10. Linux как гость виртуализации [102.6]
  11. Командная строка Bash [103.1] (вы здесь)
  12. Обработка текста фильтрами [103.2]
  13. Базовое управление файлами [103.3]
  14. Потоки, конвейеры и перенаправление [103.4]
  15. Процессы: создание, мониторинг, сигналы [103.5]
  16. Приоритеты выполнения процессов [103.6]
  17. Регулярные выражения [103.7]
  18. Редактор vi и vim [103.8]
  19. Разделы и создание файловых систем [104.1]
  20. Целостность и обслуживание ФС [104.2]
  21. Монтирование файловых систем [104.3]
  22. Урок 21. Права доступа и владение: rwx, chmod, umask и специальные биты
  23. Жёсткие и символические ссылки
  24. FHS и поиск файлов в системе [104.7]
  25. Окружение и кастомизация оболочки [105.1]
  26. Урок 25. Написание простых bash-скриптов [105.2]
  27. Графика, рабочие столы и доступность
  28. Учётные записи пользователей и групп
  29. Автоматизация задач: cron, at, таймеры [107.2]
  30. Локализация и интернационализация [107.3]
  31. Системное время и синхронизация [108.1]
  32. Системное логирование [108.2]
  33. Основы почтового агента (MTA) [108.3]
  34. Печать и CUPS [108.4]
  35. Основы интернет-протоколов [109.1]
  36. Постоянная конфигурация сети [109.2]
  37. Диагностика сети [109.3]
  38. DNS на стороне клиента [109.4]
  39. Задачи администрирования безопасности [110.1]
  40. Настройка безопасности хоста [110.2]
  41. Шифрование данных: SSH и GnuPG [110.3]
Урок 10. Командная строка Bash [103.1]

Каждый рабочий день администратора проходит в bash, и скорость работы в нем напрямую зависит от того, понимаете ли вы, что именно происходит между нажатием Enter и запуском программы. В этом уроке разберем, как оболочка хранит и наследует переменные, как находит исполняемый файл, как раскрывает то, что вы написали, и как пользоваться историей и справкой так, чтобы не печатать одно и то же по двадцать раз. Это фундамент: на нем потом стоят скрипты, systemd-юниты и автоматизация.

Изображение

Как это работает

У оболочки есть два сорта переменных. Переменные оболочки видны только текущему процессу bash. Переменные окружения помечены флагом экспорта и копируются в каждый дочерний процесс. Когда вы запускаете команду, bash делает fork, дочерний процесс наследует копию окружения родителя - и ничего из того, что дочерний процесс там поменяет, обратно к вам не вернется. Поэтому изменить окружение текущей сессии скрипт не может, только подсказать вам это сделать.

Команда export переводит обычную переменную в разряд экспортируемых. set без аргументов печатает вообще все переменные и функции оболочки, env - только экспортированное окружение. unset удаляет переменную. Запомните разницу: переменная без export существует, но дочерние процессы ее не увидят.

PATH - это список каталогов через двоеточие, по которым bash ищет исполняемый файл, когда вы пишете голое имя команды. Поиск идет слева направо, берется первое совпадение. Чтобы не сканировать диск каждый раз, bash кеширует найденные пути в хеш-таблице. Поэтому после установки программы в уже просмотренный каталог иногда нужно сбросить кеш через hash -r.

Прежде чем искать в PATH, bash раскрывает написанную строку в несколько проходов: тильда (~ в домашний каталог), переменные ($VAR), подстановка команд ($(...)), арифметика ($((...))), и в конце - глоб-шаблоны (* ? [ ]). Глоб раскрывает сама оболочка, а не программа: ls *.txt получает уже готовый список файлов. Если совпадений нет, шаблон по умолчанию остается как есть - частый источник сюрпризов.

Кавычки управляют тем, какие проходы отработают. Одинарные кавычки выключают все раскрытия - внутри буквально каждый символ. Двойные кавычки оставляют живыми $, обратные кавычки и обратный слеш, но гасят разбиение на слова и глоб. Обратный слеш экранирует один следующий символ. Правило простое: переменные, в которых могут быть пробелы или спецсимволы, всегда берите в двойные кавычки.

Команды и примеры

Переменные и окружение:

Код: Выделить всё

GREETING="привет"        # только в этой оболочке
export EDITOR=vim        # уйдет во все дочерние процессы
export PATH="$HOME/bin:$PATH"   # добавили свой каталог в начало
env | grep EDITOR        # видно в окружении
set | grep GREETING      # видно среди переменных оболочки
unset GREETING           # удалили
Поиск программ. Здесь важно понимать, чем отличаются инструменты:

Код: Выделить всё

type -a ls       # ЧЕМ является имя: alias, builtin, функция, файл - и ВСЕ варианты
which -a python3 # внешняя утилита, ищет только файлы в PATH
command -v cp    # переносимый способ узнать, как разрешится команда
type - встроенная команда bash и знает про алиасы и функции, which - отдельная программа и про них не в курсе. На экзамене это любят: type ls покажет alias, а which ls - нет. command -v - предпочтительный вариант для скриптов.

Сброс кеша путей и обход алиаса:

Код: Выделить всё

hash -r          # очистить кеш найденных команд
\ls              # обратный слеш гасит алиас, вызовет настоящий ls
command ls       # то же самое без алиаса
Подстановки и кавычки наглядно:

Код: Выделить всё

echo "Сегодня $(date +%F), ядро $(uname -r)"
echo "2+2 = $(( 2 + 2 ))"
name="мир";  echo "Двойные: $name"   # Двойные: мир
echo 'Одинарные: $name'              # Одинарные: $name
touch "файл с пробелом.txt"          # без кавычек создаст ТРИ файла
История и горячие клавиши. Переменные HISTSIZE (сколько команд в памяти) и HISTFILESIZE (сколько на диске в ~/.bash_history) задают размеры:

Код: Выделить всё

history 10       # последние 10 команд
!!               # повторить предыдущую команду (удобно с sudo !!)
!ssh             # последняя команда, начинавшаяся на ssh
!$               # последний аргумент прошлой команды
Ключевые горячие клавиши: Ctrl+R - обратный инкрементальный поиск по истории (жмите еще раз для следующего совпадения), Ctrl+A и Ctrl+E - в начало и конец строки, Ctrl+U и Ctrl+K - вырезать до начала и до конца, Ctrl+W - стереть слово слева, Ctrl+L - очистить экран, Alt+. - вставить последний аргумент.

Справка. Разделы man - это не прихоть, а способ разрешить конфликты имен:

Код: Выделить всё

man 1 printf     # 1 - пользовательские команды
man 5 passwd     # 5 - форматы файлов (файл /etc/passwd, не команда!)
man 8 mount      # 8 - администрирование, обычно root
man -k network   # поиск по короткому описанию (он же apropos)
man -f passwd    # к какому разделу относится имя (он же whatis)
Чаще всего нужны разделы 1 (команды), 5 (файлы конфигурации) и 8 (системное администрирование). В RHEL 10 и Fedora 41+ man-страницы ставятся пакетами man-pages и man-db; в Debian 13 и Ubuntu 24.04 - так же, плюс полезен help для встроенных команд bash (help export), которых в man просто нет.

Частые грабли
  • Забыли export - переменная видна в текущей оболочке, но скрипт или дочерний процесс ее не получает.
  • Изменили PATH или любую переменную в скрипте, запущенном как ./script.sh - после выхода ничего не изменилось, потому что это был отдельный процесс. Нужен source script.sh или точка: . script.sh.
  • Поставили новую программу, а bash запускает старую или говорит command not found - сработал кеш путей, лечится hash -r.
  • Переменная в двойных кавычках с пробелами разъехалась на несколько аргументов - забыли кавычки вокруг "$var".
  • which ls говорит /bin/ls, а на деле выполняется алиас с цветом - which не видит алиасы, проверяйте через type.
  • man passwd открыл команду смены пароля, а нужен был формат файла - указывайте раздел: man 5 passwd.
  • Дописали PATH в начало без $PATH в конце (PATH="$HOME/bin") - потеряли доступ ко всем системным командам в этой сессии.
Мини-лаба
  • Создайте каталог ~/bin, положите туда скрипт hello (с строкой #!/bin/bash и echo привет), сделайте chmod +x.
  • Запустите hello - убедитесь, что command not found, затем добавьте export PATH="$HOME/bin:$PATH" и запустите снова.
  • Выполните type hello и which hello, сравните вывод; затем создайте алиас alias hello='echo алиас' и снова сравните type и which.
  • Задайте COLOR=red без export, запустите bash (вложенная оболочка), проверьте echo $COLOR - пусто; выйдите, сделайте export и повторите.
  • Через Ctrl+R найдите в истории команду с chmod и выполните повторно, не печатая заново.
  • Откройте man 5 crontab и man 1 crontab, найдите разницу в содержимом; затем man -k passwd посмотрите все разделы с этим именем.
Контрольные вопросы
  • Чем отличается переменная оболочки от переменной окружения и какая команда переводит одну в другую?
  • Почему изменения PATH внутри ./script.sh не сохраняются, а внутри source script.sh - сохраняются?
  • В каком порядке bash раскрывает тильду, переменные, подстановку команд и глоб-шаблоны?
  • Что покажет type ls и что покажет which ls, если на ls есть алиас, и почему они расходятся?
  • Зачем нужна команда hash -r и в какой ситуации без нее bash запустит не тот файл?
  • Команда и файл называются одинаково (passwd) - как открыть man именно для формата файла, а не для команды?
👍3 ❤️2 🔥1 😄 🤔3
Аватара пользователя
kkppcc
Сообщения: 1
Зарегистрирован: 20 май 2026, 09:17

Re: Командная строка Bash [103.1]

Сообщение kkppcc »

А почему тогда `which` вообще ещё держат в дистрибутивах, если он не видит алиасы и функции? Перешёл на `type -a` и `command -v`, ни разу не пожалел.
👍2 ❤️1 🔥 😄 🤔1
Аватара пользователя
superkrutyh
Сообщения: 1
Зарегистрирован: 11 май 2026, 20:52

Re: Командная строка Bash [103.1]

Сообщение superkrutyh »

Поймал ровно эти грабли: правил PATH в .sh, запускал через ./, и сидел гадал почему не подхватывается. Оказалось надо было через точку source. Спасибо, теперь понятно про fork и дочерний процесс.
👍2 ❤️ 🔥1 😄 🤔
Ответить
← Предыдущая глава
Linux как гость виртуализации [102.6]
Следующая глава →
Обработка текста фильтрами [103.2]

Все главы курса «LPIC-1: администратор Linux (101 + 102)»

Поделиться темой: ✈ Telegram VK

Вернуться в «LPIC-1: администратор Linux»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость