Инструменты Linux

Терминал является основным интерфейсом к системе, и от степени владения им зависит скорость всей повседневной работы. Разница между пользователем, знающим пять команд, и пользователем, знающим тридцать, измеряется часами: первый копирует файлы в графическом файловом менеджере и просматривает журнал вручную, второй выполняет те же действия одной командной строкой, набранной за несколько секунд.

Глава выстроена по нарастающей: сначала рассматривается обустройство рабочего места, затем основы командной строки, далее утилиты, необходимые каждый день, и, наконец, диагностика в ситуации, когда система работает не так, как ожидалось. Запоминать всё подряд не требуется: достаточно знать, что подходящий инструмент существует, а подробности всегда приведены в man.

Слайды к главе. Материал главы изложен также в лекции «Инструменты Linux» с демонстрациями в терминале; слайды лекции доступны на сайте книги и в PDF.

Подготовка и окружение

Слепая печать

Первым навыком является умение печатать, не глядя на клавиатуру. Две вложенные недели окупаются годами: растёт скорость, растёт точность, а внимание постоянно остаётся на экране. В первые месяцы после переучивания скорость, набранная годами, снижается, и это является нормальным.

Инструменты для тренировки:

  • GNU Typist (gtypist), консольный тренажёр. Устанавливается через apt-get install gtypist или brew install gtypist.
  • monkeytype, современный онлайн-тренажёр.
  • www.keybr.com, ещё один популярный онлайн-тренажёр.

Эмулятор терминала

Терминал, поставляемый в комплекте с системой, обычно способен только отображать текст. Полчаса, потраченные на установку полноценного эмулятора, окупаются быстро. Требуемые возможности:

  • вкладки;
  • разделение окна на панели;
  • копирование в буфер обмена простым выделением текста;
  • ссылки, открывающиеся по щелчку;
  • плагины;
  • темы, прозрачность и прочие мелочи, повышающие удобство работы.

Рекомендуемые терминалы:

  • macOS: iTerm2
  • Linux: Terminator, Kitty, Konsole
  • Windows 10/11: Windows Terminal
  • Windows (условно-бесплатный): MobaXterm (также включает SSH-клиент, X-сервер и сетевые инструменты).

Моноширинные шрифты

В моноширинном шрифте все символы имеют одинаковую ширину, поэтому колонки, выведенные командой, не смещаются, а отступы в коде различимы визуально. Хороший терминальный шрифт, кроме того, различает плохо отличимые символы, будь то ноль и заглавная O или единица и строчная l.

  • Source Code Pro (Adobe)
  • Inconsolata (Google)
  • Anonymous Pro

Все три распространяются свободно и в большинстве дистрибутивов доступны в подключённых репозиториях.

Командные оболочки (Shell)

Оболочка представляет собой интерпретатор команд. Она разбирает набранную строку, находит нужную программу и запускает её, а терминал, отрисовывающий окно, лишь передаёт нажатия клавиш.

  • bash (Bourne-Again SHell): универсальный стандарт. Присутствует на любой машине, доступной по ssh, поэтому переносимые скрипты пишутся под него.
  • zsh (Z Shell): те же возможности плюс интеллектуальное автодополнение и богатая экосистема плагинов; настройку упрощает фреймворк Oh My Zsh. Разумный выбор для собственной рабочей машины.
  • fish (Friendly Interactive SHell): подсказки по истории, подсветка и автодополнение работают сразу, без настройки. Платой является несовместимость с синтаксисом POSIX-оболочек: скрипт, написанный для bash, в fish не запустится.

Основы командной строки

Структура команд

Команда в оболочке почти всегда является именем исполняемого файла, а не встроенной конструкцией языка. Знание того, как оболочка находит этот файл и по каким соглашениям устроены флаги, позволяет без труда читать чужие скрипты.

  • Оболочка ищет исполняемый файл по каталогам из переменной окружения $PATH и запускает его системным вызовом exec.
  • which <команда> или type <команда> показывают полный путь к исполняемому файлу команды. Флаг -a показывает все возможные пути в $PATH.
  • Флаги команд не стандартизированы, но существуют соглашения:
    • -v / --version показывают версию.
    • -h / --help показывают справку.
    • -y / -f пропускают подтверждение (yes/force).

Справка man

Основным источником информации является man (manual). Обращаться к нему следует раньше, чем к поисковой системе: в man описана версия утилиты, установленная в системе, а не та, о которой три года назад писали на форуме.

  • Пейджер: По умолчанию для просмотра используется less. Его можно изменить переменной окружения $MANPAGER (например, MANPAGER=cat).
  • Основные клавиши в less:
    • h вызывает помощь.
    • PgUp, PgDown, ↓, ↑ служат для навигации.
    • /KEYWORD запускает поиск.
    • n переходит к следующему совпадению, N к предыдущему.
    • g переносит в начало документа.
    • G переносит в конец документа.
  • man <раздел> <команда>, например man 1 bash (справка по bash из раздела «пользовательские команды»).
  • man -P 'less +/KEYWORD' bash открывает man с поиском по ключевому слову.

Управление процессами

Запущенной программой можно управлять из того же терминала. Все сочетания, перечисленные ниже, посылают процессу сигналы, устройство которых рассматривается в главе про внутреннее устройство Linux, а команды fg, bg и jobs определяют, на переднем плане процесс выполняется или в фоне.

  • Ctrl + C посылает сигнал SIGINT (завершение процесса).
  • Ctrl + \ посылает сигнал SIGQUIT (завершение с дампом памяти).
  • Ctrl + Z посылает сигнал SIGTSTP (приостановка процесса).
  • fg возвращает приостановленный процесс на передний план.
  • bg запускает приостановленный процесс в фоновом режиме.
  • jobs выводит список задач текущей оболочки с их номерами.
  • stty -a показывает настройки терминала и позволяет их изменить.

Управление вводом/выводом (I/O Redirection)

У каждой запущенной программы имеются три открытых потока, а перенаправление подменяет то, куда они ведут. На нём основаны конвейеры: вывод одной программы становится входом другой, и ни одна из них об этом не знает.

Вывод расчёта, запущенного на ночь, направляется так, чтобы результаты и ошибки попали в разные файлы: наутро сразу видно, была ли ошибка, и просматривать мегабайт накопленных чисел не придётся.

  • Потоки данных:
    • stdin (0), стандартный вход.
    • stdout (1), стандартный выход.
    • stderr (2), стандартный вывод ошибок.
  • Перенаправление:
    • команда > файл записывает stdout в файл, перезаписывая его.
    • команда >> файл дописывает stdout в конец файла.
    • команда 2> файл записывает stderr в файл.
    • команда &> файл записывает stdout и stderr в файл.
    • команда 2>&1 перенаправляет stderr в stdout.
    • команда | другая_команда передаёт stdout первой команды на stdin второй.
  • Специальные файлы:
    • /dev/null, «чёрная дыра».
    • /dev/zero, источник нулей.
    • /dev/urandom, источник псевдослучайных чисел.

Полезные помощники

Ни один из этих приёмов не требует специального изучения: достаточно однократного применения.

  • Автодополнение (completion): клавиша TAB.
    • Одно нажатие дополняет команду или файл.
    • Двойное нажатие показывает все возможные варианты.
  • История команд (~/.bash_history, ~/.zsh_history):
    • Ctrl + R запускает реверсивный поиск по истории.
    • history | grep <ключевое_слово> ищет по истории.
    • sudo !! выполняет предыдущую команду с sudo.
    • !$ подставляет последний аргумент предыдущей команды.

Ветвления, циклы и подоболочки (Subshell)

Оболочка является полноценным, хотя и неудобным, языком программирования. Циклов и условий достаточно, чтобы выполнить расчёт по сотне наборов параметров, заданных в файле, не открывая редактор. Как только скрипт превышает пару десятков строк, переписать его на Python оказывается дешевле, чем поддерживать.

  • ; разделяет команды, выполняемые последовательно.
  • Циклы и условия:
    while true; do ...; done
    for i in $(seq 1 10); do echo $i; done
    if [ "$(wc -l < file.txt)" -gt 3 ]; then ...; fi
    
  • read, встроенная команда для чтения ввода в переменные.
  • Подстановка команд (command substitution): $(команда) подставляет вывод команды в строку; сама команда выполняется в подоболочке, поэтому присвоенные в ней переменные наружу не передаются.
  • Подоболочка (subshell): ( команда; команда ) — дочерняя копия оболочки со своими переменными и текущим каталогом, так что cd внутри скобок родительский каталог не меняет.
  • [ является не элементом синтаксиса оболочки, а командой: в /usr/bin расположена одноимённая программа, хотя bash и zsh выполняют собственную встроенную. Отсюда и требование ставить пробелы вокруг скобок: без них это будет другое имя команды. Подробности: man [ или man test.

Полезные команды и утилиты

Ниже рассматриваются инструменты, необходимые почти в каждой рабочей задаче: поиск файлов, сохранение сессии при обрыве связи, редактирование конфигурации на удалённом сервере и обработка текстового потока.

Find и многопоточность

Связка find и xargs применяет команду ко всем файлам, удовлетворяющим условию. Флаг -P у xargs превращает её в простейший параллельный запуск с заданным числом одновременных процессов. Выигрыш растёт с числом процессов, пока задача ограничена процессором; на обработке, ограниченной диском, он выходит на насыщение заметно раньше.

  • find осуществляет мощный поиск файлов и директорий.
    • Пример: find /etc -type f -name "nginx*"
  • xargs передаёт результаты из stdin в аргументы другой команды.
    • -P <N> запускает до N процессов параллельно.
    • -n1 передаёт по одному аргументу за раз.
    • -0 читает имена, разделённые нулевым байтом, — пара к find -print0; без неё имена с пробелами будут разбиты на части.
    • Пример: find /data -type f -print0 | xargs -0 -P10 -n1 md5sum
  • GNU parallel служит более мощной альтернативой xargs для параллельного выполнения.

Управление сессиями: screen и tmux

Расчёт, запущенный по ssh, завершается вместе с обрывом связи, а связь с кластером обрывается регулярно. screen и tmux решают эту проблему: сессия, отвязанная от терминала, продолжает работать на сервере, а пользователь подключается к ней и отключается в любой момент, в том числе с другой машины.

  • screen:

    • screen создаёт новую сессию.
    • Ctrl + A, D отключает от сессии (detach).
    • screen -ls выводит список сессий.
    • screen -r <session> подключает к сессии.
  • tmux (рекомендуется):

    • tmux создаёт сессию.
    • Ctrl + B, D отключает от сессии.
    • tmux ls выводит список сессий.
    • tmux a -t <session> подключает к сессии.
    • Интеграция с iTerm2: tmux -CC.
  • watch -d -n1 "команда" выполняет команду раз в секунду и подсвечивает меняющиеся значения.

Редактирование текста

Рано или поздно потребуется править конфигурацию на сервере без графической оболочки, поэтому необходимо владеть хотя бы одним консольным редактором. Выбор является вопросом вкуса, однако выйти из незнакомого редактора, открывшегося вместо привычного, обязан уметь каждый.

  • Vim:
    • Мощный редактор, присутствующий на любой машине, но с непривычным управлением, которое требует отдельного освоения.
    • vimtutor, встроенный интерактивный учебник на полчаса.
    • Основы: i включает режим вставки, ESC возвращает в нормальный режим, :wq сохраняет и выходит, :q! выходит без сохранения.
    • vimdiff file1 file2 сравнивает файлы.
  • Emacs: другой мощный редактор со своей философией и своими сторонниками.
  • Git: система контроля версий, без которой сегодня не обходится ни один проект; ей посвящена отдельная глава. Для сообщения коммита git открывает редактор, заданный настройкой core.editor или переменными окружения VISUAL и EDITOR. Если ничего не задано, в Ubuntu и Debian открывается системный редактор по умолчанию, обычно nano (подсказки клавиш показаны внизу экрана: Ctrl+O сохраняет файл, Ctrl+X выходит), а в macOS и большинстве других систем — vi. Привычный редактор задаётся явно: git config --global core.editor vim.

Потоковая обработка текста

Каждая из этих утилит выполняет над текстовым потоком одну операцию, а соединяются они конвейером. Разбор журнала, извлечение колонки чисел, подсчёт уникальных значений укладываются в одну строку, набранную по ходу работы. Как только разбор перестаёт быть разовым и становится частью повторяемого конвейера обработки данных, его лучше переписать на Python: цепочку из пяти awk и sed через месяц невозможно ни прочитать, ни отладить.

  • grep фильтрует строки по регулярному выражению.
  • awk, целый язык для обработки текста, основанный на колонках.
  • sed, потоковый редактор, правящий текст на лету (замена, удаление строк и т.д.).
  • cut извлекает конкретные колонки.
  • head и tail выводят начало и конец файла, а tail -f показывает строки, дописываемые в настоящий момент.
  • tr заменяет или удаляет символы.
  • wc считает строки, слова и символы.
  • sort сортирует строки.
  • uniq отфильтровывает повторяющиеся строки.

Тренажёры: grepexercises, sedexercises, awkexercises (устанавливаются через pip).

Практика: The Command Line Murders, детективный квест, расследуемый исключительно командами в терминале: https://github.com/veltman/clmystery


Диагностика и поиск проблем

Последняя часть посвящена ситуации, когда система работает не так, как ожидалось: расчёт стал необъяснимо медленным, место на диске закончилось, сервис не отвечает.

Общий принцип диагностики состоит в движении сверху вниз по подсистемам (процессор, память, диск, сеть) с принятием на каждом шаге решения, здесь ли узкое место или дальше. Каждое предположение необходимо подтверждать измерением на работающей системе.

Методология и ресурсы

Карта инструментов, охватывающая всю систему целиком, составлена Бренданом Греггом (Brendan Gregg). На его сайте https://www.brendangregg.com/linuxperf.html приведены схемы, где каждая подсистема ядра подписана инструментами, которыми она измеряется. Схем четыре:

  • Linux Observability Tools для наблюдения за работающей системой;
  • Linux Static Performance Tools для сбора статической конфигурации, заданной до всякой нагрузки;
  • Linux Benchmarking Tools для нагрузочного тестирования;
  • Linux Tuning Tools для подстройки параметров ядра.

Первую, самую насыщенную, рекомендуется распечатать и разместить рядом с рабочим местом. У того же автора имеется книга «Systems Performance: Enterprise and the Cloud», справочник по всему, что в Linux измеримо.

Мини-топ полезных утилит

  • Мониторинг процессов и системы:
    • top и htop показывают процессы в интерактивном режиме.
    • atop ведёт расширенный мониторинг и позволяет записывать данные в файл.
    • pidof находит PID по имени процесса.
    • ps fauxw | less даёт подробный список запущенных процессов.
  • Диски и файловая система:
    • df -h и df -ih показывают место на дисках и inodes.
    • du -sh /path/* показывает размер директорий.
    • iostat -x 1 выводит статистику ввода-вывода.
  • Сеть:
    • ss -s и netstat -ntlp выводят статистику сокетов и открытые порты.
    • ping, traceroute и mtr диагностируют сетевую связность.
    • tcpdump работает «сниффером», перехватывающим сетевые пакеты.
    • ethtool eth0 показывает настройки и статистику сетевого интерфейса.
  • Прочее:
    • lsof -i:ПОРТ показывает, какой процесс держит порт, а lsof -p $PID — какие файлы и сокеты открыл процесс.
    • strace -fp $PID и strace $cmd трассируют системные вызовы.
    • dmesg -T показывает сообщения ядра с проставленными временными метками.
    • perf top -F99 профилирует систему в реальном времени.
    • curl — универсальный инструмент для работы с HTTP и сетью.

Заключение

Осваивать всё сразу не требуется. Рекомендуемый порядок следующий: сначала слепая печать и полноценный терминал, затем привычка обращаться к man вместо поисковой системы, затем tmux, позволяющий не терять расчёты на кластере при обрыве связи, и уже после этого grep, awk и sed. Каждый следующий инструмент осваивается на реальной задаче, а не заранее и впрок.

Мерилом здесь является не число выученных команд, а то, сколько действий, прежде выполнявшихся вручную, теперь выполняется одной набранной строкой.

Задание. Долгий расчёт, переживающий закрытие сессии: «Работа с долгоиграющими процессами».

Задание. Обустройство рабочего места в терминале и выполнение набора упражнений: «Настройка окружения и работа с утилитами».