Блок 10
Процессы и службы
Мы уже несколько раз упоминали слово «процесс» на протяжении курса, но никогда не раскрывали его полностью — пришло время это исправить. В этом блоке мы разберём, как Linux управляет запущенными пр…
Введение в блок
Мы уже несколько раз упоминали слово «процесс» на протяжении курса, но никогда не раскрывали его полностью — пришло время это исправить. В этом блоке мы разберём, как Linux управляет запущенными программами, что такое демоны и службы, познакомимся с systemd — центральной системой управления службами в современном Ubuntu, научимся читать системные журналы через journalctl, и освоим планировщики задач cron и at для автоматического запуска команд по расписанию. Этот блок — прямая подготовка к пониманию того, как на сервере работают такие вещи, как веб-серверы (Блок 19) и базы данных, а также к автоматизации из Блока 15.
Урок 10.1. Что такое процесс, PID, дерево процессов
Понять фундаментальное понятие процесса — единицы работающей программы в Linux — и научиться ориентироваться в иерархии процессов, что является основой для всего дальнейшего материала этого блока.
Теория
Мы уже неоднократно упоминали в курсе (начиная с урока 4.4), что каждая выполняемая команда — это запуск отдельной программы. Когда программа запускается и начинает выполняться, операционная система создаёт для неё процесс (process) — рабочую единицу, представляющую конкретный экземпляр выполняемой программы вместе со всем её текущим состоянием: используемой памятью, открытыми файлами, текущим положением выполнения кода, и так далее. Важно различать: программа — это файл на диске (например, /usr/bin/bash», как мы видели в уроке 5.8 через which»), а процесс — это уже работающий, активный экземпляр этой программы в памяти компьютера в данный конкретный момент. Одна и та же программа может быть запущена одновременно в виде нескольких независимых процессов — например, если вы откроете несколько окон терминала, каждое из них будет отдельным процессом Bash, хотя все они запущены из одного и того же файла программы.
Каждому процессу при его создании присваивается уникальный числовой идентификатор — PID (Process ID), аналогично тому, как каждому пользователю присваивается UID (вспомните Блок 8). PID используется системой (и вами как администратором) для однозначной идентификации конкретного процесса среди множества других, одновременно работающих в системе.
Процессы в Linux организованы в иерархическую структуру дерева: каждый процесс (кроме самого первого) создаётся другим, уже существующим процессом — этот создающий процесс называется родительским процессом (parent process), а созданный им — дочерним процессом (child process). У родительского процесса, в свою очередь, тоже есть свой родитель, и так далее, вплоть до самого первого процесса в системе, запускаемого напрямую ядром при загрузке — мы уже упоминали его вскользь в уроке 2.2, говоря о процессе загрузки, и подробно вернёмся к нему в следующем уроке этого блока, когда будем разбирать systemd. Идентификатор родительского процесса конкретного процесса называется PPID (Parent Process ID).
Эта иерархическая структура — не просто абстрактная организационная деталь: она напрямую влияет на практическое поведение системы. Например, когда вы закрываете окно терминала (родительский процесс которого — сессия Bash), обычно автоматически завершаются и все дочерние процессы, запущенные из этого терминала (если только они не были явно «отсоединены» от родителя специальными средствами, к чему мы вернёмся в уроке 10.4).
Практика
Шаг 1. Откройте терминал и узнайте PID текущей сессии самого Bash с помощью специальной переменной окружения (аналогично уже знакомым нам $HOME, $SHELL» из Блока 6): echo $$».
Что вы увидите: числовой идентификатор — PID текущего процесса Bash, в котором вы сейчас работаете.
[Скриншот терминала]
Шаг 2. Узнайте PID родительского процесса для текущего Bash с помощью переменной $PPID: `echo $PPID».
Что вы увидите: другой числовой идентификатор — обычно это PID программы-терминала (эмулятора терминала, вспомните урок 4.1), в котором запущена ваша сессия Bash, то есть непосредственного родителя вашей текущей оболочки.
Шаг 3. Запустите новый, вложенный процесс Bash прямо изнутри текущего (мы уже упоминали такую возможность в уроке 4.2): `bash».
Что произойдёт: вы окажетесь во вложенной, новой сессии Bash — приглашение командной строки может выглядеть точно так же, как и раньше, но технически это уже совершенно другой, новый процесс.
Шаг 4. Проверьте PID и PPID этой новой, вложенной сессии: echo $$» и echo $PPID».
Что вы увидите: новый PID (отличный от того, что вы видели на шаге 1) — а PPID этой новой сессии должен в точности совпадать с PID исходной сессии, которую вы записали на шаге 1, наглядно подтверждая иерархическую связь родитель-потомок.
[Скриншот результата]
Шаг 5. Завершите вложенную сессию командой `exit» (мы уже упоминали эту команду в уроке 4.2), чтобы вернуться в исходную, родительскую сессию Bash.
Разбор команд
Специальные переменные $$ и $PPID
- Назначение:**
$$» содержит PID текущего процесса Bash;$PPID» содержит PID его родительского процесса. - Реальные примеры использования:** эти переменные особенно полезны при написании Bash-скриптов (тема Блока 15), например для создания уникальных временных файлов, чьё имя гарантированно не совпадёт с именами файлов, создаваемых другими одновременно работающими экземплярами того же скрипта (используя
$$как часть уникального имени файла).
Возможные ошибки
- Ошибка:** путаница между понятиями «программа» и «процесс», аналогичная той, что мы уже разбирали для файлов и их имён в Блоке 5.
Почему возникает: в повседневной речи слова «программа» и «процесс» часто используются как взаимозаменяемые синонимы.
Как определить: непонимание, почему одна и та же программа (например, Bash) может быть представлена сразу несколькими разными процессами с разными PID одновременно, как мы только что продемонстрировали на практике.
Как исправить: запомнить чёткое разделение: программа — это файл на диске; процесс — это конкретный работающий экземпляр этой программы в памяти, и таких экземпляров, каждый со своим уникальным PID, может быть одновременно запущено сколько угодно.
Как избежать: мысленно возвращаться к только что проведённому практическому эксперименту с вложенным `bash» при возникновении сомнений в этом различии.
Практические задания
- Откройте два отдельных окна терминала (как мы уже практиковали в предыдущих блоках) и сравните значения `$$» в каждом из них — убедитесь, что это разные, независимые процессы с разными PID, хотя оба запущены из одной и той же программы Bash.
- Запустите вложенную сессию Bash дважды подряд (
bash», затем ещё разbash», не выходя из первой вложенной сессии) и проверьте PID и PPID на каждом уровне вложенности, зафиксировав в конспекте получившуюся цепочку родитель-потомок из трёх уровней. - Своими словами объясните в конспекте, почему закрытие окна терминала обычно приводит к завершению всех процессов, запущенных внутри него, опираясь на понятие иерархии родительских и дочерних процессов.
Проверка знаний
Вопрос 1. Что такое PID и зачем он нужен?
Ответ: PID (Process ID) — уникальный числовой идентификатор, присваиваемый каждому процессу при его создании. Он используется системой и администратором для однозначной идентификации конкретного процесса среди множества других, одновременно работающих в системе.
Вопрос 2. Как называется процесс, который создал данный конкретный процесс, и как называется идентификатор этого создающего процесса?
Ответ: Он называется родительским процессом (parent process), а его идентификатор — PPID (Parent Process ID).
Итоги урока
Вы изучили: понятия процесса, PID, PPID, и иерархическую структуру дерева процессов в Linux.
Вы умеете: определять PID и PPID текущей сессии, наблюдать создание дочерних процессов на практике.
В следующем уроке потребуется: это понимание, чтобы освоить инструменты для просмотра всех работающих в системе процессов — ps, top, htop.
Урок 10.2. Просмотр процессов: `ps`, `top`, `htop`
Освоить инструменты для просмотра списка всех работающих в системе процессов — необходимый навык для диагностики проблем с производительностью (тема Блока 18) и общего понимания того, что происходит внутри системы в данный момент.
Теория
Мы уже мельком использовали команду ps в уроке 6.3, при знакомстве с конвейерами, но не разбирали её подробно. Пришло время это исправить.
ps (process status, «статус процессов») — команда, которая выводит одномоментный «снимок» списка процессов, работающих в системе на момент выполнения команды. В отличие от следующих двух инструментов этого урока, `ps» не обновляет информацию автоматически в реальном времени — она показывает статичную картину, актуальную ровно на момент запуска, и для получения обновлённых данных команду нужно выполнить заново.
top (буквально «вершина», в смысле «самые ресурсоёмкие процессы наверху списка») — интерактивная, постоянно обновляющаяся в реальном времени программа мониторинга процессов, показывающая не только список работающих процессов, но и общую информацию о загрузке системы: использование процессора, оперативной памяти, количество запущенных процессов, и так далее — всё это обновляется автоматически, обычно каждые несколько секунд.
htop — значительно более удобная, современная и наглядная альтернатива top, с цветовой индикацией, более удобной навигацией с помощью мыши и клавиш, и дополнительными возможностями вроде древовидного отображения иерархии процессов (вспомните материал предыдущего урока про родительские и дочерние процессы). В отличие от ps и top, которые предустановлены в Ubuntu по умолчанию, htop» обычно требует отдельной установки через уже хорошо знакомый нам из Блока 9 apt install».
Практика
Шаг 1. Выполните простейший вариант ps» без параметров: ps».
Что вы увидите: короткий список, обычно содержащий всего пару строк — по умолчанию, без дополнительных параметров, ps» показывает только процессы, запущенные именно в текущем терминале текущим пользователем (например, саму сессию Bash и, возможно, сам процесс ps`).
[Скриншот терминала]
Шаг 2. Выполните расширенный вариант, показывающий все процессы в системе от всех пользователей, который мы уже использовали в уроке 6.3: ps aux» (сочетание трёх опций без дефиса перед ними — историческая особенность синтаксиса ps, унаследованная от классического BSD-варианта UNIX, о котором мы упоминали в уроке 1.1; параметр a» означает показать процессы всех пользователей, u» — показать в удобном для человека, «user-oriented» формате с дополнительными столбцами, x» — включить в список также процессы, не связанные с каким-либо терминалом, например системные службы).
Что вы увидите: длинный список всех процессов, работающих в системе, со столбцами PID, использование CPU и памяти в процентах, время запуска, и командой, которой процесс был запущен.
Шаг 3. Скомбинируем ps aux» с уже хорошо знакомыми нам инструментами обработки текста из Блока 6, чтобы отсортировать процессы по использованию памяти от наибольшего к наименьшему: ps aux --sort=-%mem | head -n 10» (параметр --sort=-%mem» указывает сортировать по столбцу использования памяти в убывающем порядке — знак минус перед именем столбца в этом конкретном синтаксисе ps» означает именно убывающий порядок).
Что вы увидите: десять процессов, потребляющих больше всего оперативной памяти на данный момент.
[Скриншот результата]
Шаг 4. Запустите интерактивный мониторинг через top: `top».
Что вы увидите: постоянно обновляющийся экран с общей сводкой по системе вверху (загрузка процессора, использование памяти, количество процессов) и списком отдельных процессов ниже, отсортированным по умолчанию по загрузке процессора.
[Скриншот терминала]
Шаг 5. Пока находитесь внутри top», попробуйте нажать клавишу M» (заглавная), чтобы пересортировать список по использованию памяти вместо процессора.
Шаг 6. Выйдите из top», нажав клавишу q» (аналогично уже знакомому нам поведению из less» и man`, изученных в предыдущих блоках).
Шаг 7. Установите htop, если он ещё не установлен, используя уже хорошо знакомый нам из Блока 9 APT: sudo apt update» и sudo apt install htop».
Шаг 8. Запустите htop: `htop».
Что вы увидите: значительно более наглядный, цветной интерфейс с графическими индикаторами загрузки каждого отдельного ядра процессора и использования памяти вверху экрана, и удобным, часто уже отсортированным списком процессов ниже.
[Скриншот результата]
Шаг 9. Выйдите из htop, нажав клавишу q» (или F10», ещё один альтернативный способ выхода, часто подсказываемый прямо в нижней части интерфейса htop).
Разбор команд
Команда ps
- Назначение:** показывает одномоментный список работающих процессов.
- Синтаксис:**
ps [опции] - Основные параметры:**
aux» (все процессы всех пользователей в удобном формате, наиболее часто используемая комбинация);-ef» (альтернативный, но концептуально похожий вариант того же самого, использующий синтаксис System V UNIX вместо BSD, о различии которых мы упоминали в теории); `--sort=столбец» (сортировка по указанному столбцу, знак минус перед именем означает убывающий порядок). - Реальные примеры использования:**
ps aux | grep firefox» (комбинируя уже хорошо знакомые нам конвейер иgrep» из Блока 6) — найти PID и подробную информацию о конкретном запущенном процессе по имени.
Команда top
- Назначение:** интерактивный, обновляющийся в реальном времени мониторинг процессов и общей загрузки системы.
- Синтаксис:**
top [опции] - Полезные горячие клавиши внутри интерактивного режима:**
M» (сортировка по памяти),P» (сортировка по загрузке процессора, обычно установлена по умолчанию),k» (позволяет ввести PID процесса для его завершения прямо изнутриtop, забегая немного вперёд к теме следующего урока),q» (выход).
Команда htop
- Назначение:** более удобная, наглядная альтернатива
topс расширенными возможностями. - Синтаксис:**
htop [опции] - Полезные горячие клавиши:** аналогично
top, но с дополнительным удобством — многие действия доступны через нажатие функциональных клавиш F1–F10, подсказки к которым отображаются прямо в нижней части интерфейса, что делаетhtop» значительно более интуитивным для новичка по сравнению сtop`.
Возможные ошибки
- Ошибка:** запуск простого
ps» без параметров в ожидании увидеть полный список всех процессов системы, аналогичноps aux».
Почему возникает: непонимание, что поведение `ps» по умолчанию (без параметров) сильно ограничено — показывает только процессы текущего терминала.
Как определить: неожиданно короткий, из одной-двух строк, результат выполнения команды.
Как исправить: добавить параметр `aux» для получения полной картины по всей системе.
Как избежать: запомнить, что ps aux» — это, по сути, тот стандартный, наиболее полезный на практике вариант использования команды, который стоит использовать по умолчанию для большинства реальных задач диагностики, а не голый ps» без параметров.
Практические задания
- Выполните
ps aux» и найдите в результате процесс, соответствующий вашей текущей сессии Bash, сверив его PID со значением переменной$$», которую вы уже изучали в предыдущем уроке. - Запустите `htop» и понаблюдайте за системой в течение минуты, попробовав запустить какую-либо ресурсоёмкую задачу в другом окне (например, повторить генерацию большого файла из Блока 6) и заметить, как это отражается на графиках загрузки процессора в реальном времени.
- Сравните списки процессов, показываемые
top» иhtop» по умолчанию, и запишите в конспект, какие визуальные и практические отличия вы заметили между этими двумя инструментами.
Проверка знаний
Вопрос 1. В чём принципиальное отличие ps от top/`htop» с точки зрения обновления информации?
Ответ: ps показывает одномоментный, статичный «снимок» списка процессов на момент выполнения команды и не обновляется автоматически. top и htop, напротив, являются интерактивными программами, постоянно обновляющими отображаемую информацию в реальном времени, без необходимости повторного запуска команды.
Вопрос 2. Что означают буквы a, u, x» в часто используемой комбинации ps aux`?
Ответ: a» — показать процессы всех пользователей; u» — показать в удобном для человека формате с дополнительными столбцами; `x» — включить процессы, не связанные с каким-либо терминалом (например, системные службы).
Итоги урока
Вы изучили: три инструмента просмотра процессов — ps (статичный снимок), top и htop (интерактивный мониторинг в реальном времени).
Вы умеете: просматривать полный список процессов системы, сортировать его по различным критериям, использовать интерактивные инструменты мониторинга.
В следующем уроке потребуется: это умение находить нужный процесс по PID или имени, чтобы научиться управлять его выполнением — приостанавливать и завершать процессы.
Урок 10.3. Управление процессами: сигналы, `kill`, `killall`, `nice`/`renice`
Освоить механизм сигналов и научиться корректно завершать, приостанавливать и управлять приоритетом работающих процессов — важный практический навык для ситуаций, когда программа «зависла» или потребляет слишком много ресурсов.
Теория
Сигнал (signal) — это специальное, стандартизированное сообщение, которое операционная система (или другой процесс, обладающий соответствующими правами) может отправить работающему процессу, чтобы уведомить его о необходимости совершить определённое действие — чаще всего связанное с завершением работы, но не только. Каждый сигнал имеет как числовой код, так и удобное текстовое имя. Разберём наиболее практически важные из них:
SIGTERM (сигнал номер 15) — «вежливая» просьба корректно завершить работу. Получив этот сигнал, хорошо спроектированная программа должна корректно завершить текущие операции (например, сохранить несохранённые данные, закрыть открытые файлы и сетевые соединения) и только после этого действительно завершиться. Это сигнал, отправляемый по умолчанию, если не указано иное.
SIGKILL (сигнал номер 9) — принудительное, немедленное завершение процесса, без какой-либо возможности для самой программы корректно завершить свою работу. Этот сигнал обрабатывается не самой программой, а непосредственно ядром системы, и не может быть проигнорирован или перехвачен программой ни при каких обстоятельствах (в отличие от SIGTERM, который теоретически может быть проигнорирован специально написанной для этого программой) — это своего рода «последний довод», используемый только тогда, когда более вежливый SIGTERM не сработал.
SIGSTOP (сигнал номер 19) — приостанавливает выполнение процесса, не завершая его полностью (процесс как бы «замораживается», продолжая занимать память, но не потребляя больше процессорного времени).
SIGCONT (сигнал номер 18) — возобновляет ранее приостановленный сигналом SIGSTOP процесс.
Практическое правило хорошего администрирования: всегда сначала пробовать «вежливый» SIGTERM, и только если процесс не реагирует на него в течение разумного времени (что может указывать на действительно серьёзное зависание программы) — прибегать к принудительному SIGKILL, понимая, что это может привести к потере несохранённых данных этой программы.
Помимо управления самим фактом работы процесса, существует также понятие приоритета процесса — числового значения (в диапазоне от -20 до 19 в Linux), определяющего, насколько «настойчиво» процесс претендует на процессорное время по сравнению с другими одновременно работающими процессами при их конкуренции за ограниченные ресурсы. Меньшее число (вплоть до -20) означает более высокий приоритет («более вежливый» к системе термин «nice», который мы разберём в разборе команд, парадоксальным образом означает как раз обратное — насколько процесс «уступчив», а не насколько он «важен»: высокое значение nice означает низкий приоритет, то есть процесс охотно уступает процессорное время другим), значение по умолчанию для обычных процессов — 0.
Практика
Шаг 1. Запустим тестовый процесс, который будет работать долго, чтобы было что завершать — используем уже знакомую нам команду sleep» из Блока 4, но на этот раз запустим её в фоновом режиме с помощью символа &» (мы упоминали эту возможность вскользь ещё в уроке 4.5, но не практиковали подробно; полноценно фоновые задачи разберём в следующем уроке этого блока, а пока используем эту конструкцию просто как удобный способ создать долго работающий тестовый процесс, не блокируя весь терминал): `sleep 300 &».
Что произойдёт: терминал выведет число — это PID только что запущенного фонового процесса `sleep», и сразу же вернёт вам доступное приглашение командной строки, не дожидаясь завершения всех 300 секунд.
[Скриншот терминала]
Шаг 2. Найдите этот процесс через ps (используя уже изученный в предыдущем уроке grep»): ps aux | grep sleep».
Шаг 3. Отправьте этому процессу «вежливый» сигнал SIGTERM с помощью команды kill, подставив реальный PID, полученный на шаге 1 или найденный на шаге 2: kill PID_процесса» (по умолчанию, без явного указания номера сигнала, kill» отправляет именно SIGTERM).
Шаг 4. Проверьте, что процесс действительно завершился: ps aux | grep sleep» — теперь в результатах не должно быть исходного процесса sleep 300» (может остаться лишь сама строка выполняемого сейчас grep sleep, что является нормальным, ожидаемым артефактом самого поиска).
[Скриншот результата]
Шаг 5. Запустите новый тестовый фоновый процесс sleep 300 &» ещё раз, чтобы потренировать SIGKILL. Отправьте принудительный сигнал, явно указав его номер через параметр -9 (соответствующий SIGKILL, как мы уже знаем из теории): kill -9 PID_процесса».
Шаг 6. Потренируем killall — команду, которая ищет процессы по имени программы, а не по PID, и может завершить сразу несколько процессов с одинаковым именем одной командой: запустите сразу три тестовых фоновых процесса sleep: sleep 300 &», sleep 300 &», sleep 300 &» (три отдельные команды подряд), а затем завершите их все одной командой: killall sleep».
Шаг 7. Проверьте результат: `ps aux | grep sleep» — все три тестовых процесса должны были завершиться одновременно.
Шаг 8. Потренируем управление приоритетом. Запустите процесс с изменённым приоритетом с помощью команды nice: nice -n 10 sleep 300 &» (параметр -n 10» устанавливает значение nice равным 10, то есть более низкий, «уступчивый» приоритет по сравнению со стандартным значением 0).
Шаг 9. Проверьте установленный приоритет через ps» с дополнительным параметром -o» (output format, позволяющим явно указать, какие именно столбцы вывести): ps -o pid,ni,cmd | grep sleep» (столбец ni» как раз показывает значение nice).
Шаг 10. Завершите оставшийся тестовый процесс: `killall sleep».
Разбор команд
Команда kill
- Назначение:** отправляет указанный сигнал процессу с заданным PID.
- Синтаксис:**
kill [-номер_сигнала] PID - Основные параметры:** без явного номера сигнала — отправляется SIGTERM (15) по умолчанию;
-9» — отправить SIGKILL (принудительное завершение);-l» (list, показать полный список всех доступных именованных сигналов с их номерами). - Типичные ошибки:** сразу использовать `-9» (SIGKILL) в качестве первой попытки завершить процесс, минуя более вежливый SIGTERM.
Почему это проблема: принудительное завершение не даёт программе шанса корректно сохранить данные или освободить используемые ресурсы, что может привести к повреждению файлов или другим нежелательным побочным эффектам.
Как избежать: придерживаться практического правила «сначала вежливо, потом принудительно» — всегда пробовать обычный kill (SIGTERM) первым, и прибегать к `-9» только если процесс явно не реагирует спустя разумное время ожидания.
Команда killall
- Назначение:** отправляет указанный сигнал (по умолчанию тоже SIGTERM) всем процессам с заданным именем программы, а не одному конкретному PID.
- Синтаксис:**
killall [-номер_сигнала] имя_программы - Реальные примеры использования:** `killall firefox» — завершить все процессы браузера Firefox одной командой, что удобно, если открыто много окон/вкладок, порождающих несколько отдельных связанных процессов.
- Типичные ошибки:** случайное завершение большего числа процессов, чем предполагалось, если несколько разных, не связанных друг с другом задач случайно используют программы с одинаковым именем.
Способы исправления: для более точечного управления конкретным единственным процессом использовать именно kill» с явным указанием PID, а не killall» по имени, если есть риск случайного захвата «лишних» процессов.
Команды nice/renice
- Назначение:**
niceзапускает новый процесс с заданным изменённым приоритетом;reniceизменяет приоритет уже работающего процесса. - Синтаксис:**
nice -n значение команда» /renice значение -p PID» - Реальные примеры использования:** `nice -n 15 tar -czvf backup.tar.gz большая_папка/» — запустить ресурсоёмкий процесс архивирования (вспомните Блок 6) с пониженным приоритетом, чтобы он не мешал другим, более важным задачам, активно конкурирующим за процессорное время в этот же момент.
Возможные ошибки
- Ошибка:** попытка завершить критически важный системный процесс без полного понимания последствий, что может привести к нестабильности или полной неработоспособности системы.
Почему возникает: недостаточная осторожность при работе с kill/killall, особенно в сочетании с широкими правами `sudo», необходимыми для завершения процессов, принадлежащих другим пользователям или системным службам.
Как определить: система становится нестабильной, перестают работать связанные функции сразу после завершения определённого процесса.
Как исправить: в большинстве случаев потребуется перезагрузка системы для восстановления работоспособности; если критически важная служба была случайно завершена (а не полностью удалена), её часто можно перезапустить штатным образом уже через systemd, тему которого разберём в следующем уроке.
Как избежать: всегда точно идентифицировать процесс перед его завершением (через ps aux | grep, как мы практиковали), и особенно осторожно относиться к завершению любых процессов с `sudo», чьё точное назначение вам не до конца понятно.
Практические задания
- Повторите полный цикл работы с
kill(SIGTERM и SIGKILL) на новых тестовых процессахsleep, самостоятельно, без подглядывания в инструкцию. - Запустите три тестовых процесса
sleep» с разными значениями nice (например, -5, 0, 10) и сравните их приоритеты черезps -o pid,ni,cmd`, объяснив в конспекте своими словами, какое значение соответствует наивысшему, а какое — наинизшему приоритету. - Своими словами объясните в конспекте (не подглядывая), почему принято сначала пробовать SIGTERM и только потом, при необходимости, SIGKILL, а не сразу использовать принудительное завершение для скорости.
Проверка знаний
Вопрос 1. В чём разница между сигналами SIGTERM и SIGKILL?
Ответ: SIGTERM — «вежливая» просьба корректно завершить работу, которую программа может обработать самостоятельно (сохранить данные, закрыть соединения) перед реальным завершением. SIGKILL — принудительное, немедленное завершение, обрабатываемое ядром напрямую, не дающее программе никакой возможности корректно завершить свою работу.
Вопрос 2. Что означает более высокое числовое значение nice — более высокий или более низкий приоритет процесса?
Ответ: Более высокое значение nice означает более низкий приоритет (процесс более «уступчив» другим процессам в конкуренции за процессорное время). Более низкое значение (вплоть до отрицательных чисел до -20) означает более высокий приоритет.
Итоги урока
Вы изучили: понятие сигналов (SIGTERM, SIGKILL, SIGSTOP, SIGCONT), команды kill, killall» для управления процессами, и команды nice/renice» для управления их приоритетом.
Вы умеете: корректно и принудительно завершать процессы, запускать процессы с заданным приоритетом.
В следующем уроке потребуется: это понимание управления процессами, чтобы освоить работу с фоновыми и foreground-задачами более полно.
Урок 10.4. Фоновые и foreground-задачи: `&`, `jobs`, `bg`, `fg`, `nohup`
Полноценно освоить механизм фоновых задач, который мы уже частично использовали в предыдущем уроке (символ &), понять разницу между foreground- и background-выполнением, и научиться переключаться между этими режимами для уже запущенных команд.
Теория
Когда вы выполняете обычную команду в терминале, она работает в так называемом foreground-режиме («на переднем плане») — терминал ожидает завершения этой команды, не позволяя вам вводить новые команды, пока текущая не завершится (мы уже наблюдали это поведение с командой tail -f» в уроке 6.4 и sleep» в уроке 4.5, где для продолжения работы требовалось либо дождаться завершения, либо прервать выполнение через Ctrl+C).
Фоновый режим (background), который мы уже частично применяли в предыдущем уроке через символ `&», позволяет запустить команду так, чтобы терминал сразу же возвращал управление, не дожидаясь её завершения — команда продолжает работать «в фоне», параллельно с тем, как вы можете вводить новые команды в том же самом окне терминала.
Что делать, если вы уже запустили команду в foreground-режиме (без &), а теперь хотите отправить её в фон, не завершая работу? Для этого существует комбинация из горячей клавиши и команды:
Ctrl+Z — приостанавливает (посылает сигнал SIGSTOP, изученный в предыдущем уроке) текущую foreground-задачу, возвращая управление терминалом, но не завершая саму задачу — она просто «замораживается» в приостановленном состоянии.
bg (background) — возобновляет последнюю приостановленную задачу, но уже в фоновом режиме (аналогично отправке сигнала SIGCONT, но с дальнейшей работой именно в фоне, а не на переднем плане).
fg (foreground) — возвращает фоновую задачу обратно в foreground-режим, «на передний план», к которому терминал снова будет ожидать её завершения.
jobs — показывает список всех фоновых и приостановленных задач, связанных именно с текущей сессией терминала, вместе с их порядковым номером (job number) — не путать с уже знакомым нам PID: номер задачи (job number) — это отдельная, более простая нумерация, актуальная только в пределах конкретной сессии терминала, тогда как PID — это глобальный, общесистемный идентификатор.
Важная практическая деталь, о которой стоит явно упомянуть, вспоминая материал предыдущего урока про иерархию процессов: и обычные foreground-задачи, и фоновые задачи, запущенные через &, остаются дочерними процессами текущей сессии терминала — а значит, при закрытии самого терминала (или явном завершении родительского процесса Bash) они, как правило, тоже автоматически завершаются, несмотря на то, что формально работали «в фоне». Чтобы действительно «отвязать» процесс от родительской сессии терминала, позволяя ему продолжать работу даже после закрытия терминала, используется специальная команда:
nohup (no hang up, «без отключения» — историческое название, связанное с эпохой, когда завершение сессии терминала физически называлось «hang up», по аналогии с положить телефонную трубку) — запускает команду таким образом, что она игнорирует сигнал, который обычно посылается дочерним процессам при закрытии родительского терминала, продолжая работать даже после его закрытия.
Практика
Шаг 1. Запустите команду sleep 300» в обычном, foreground-режиме, без &: sleep 300».
Что произойдёт: терминал «зависнет» в ожидании, как мы уже наблюдали для похожих команд ранее в курсе.
Шаг 2. Приостановите эту задачу сочетанием `Ctrl+Z».
Что произойдёт: вы увидите сообщение вида [1]+ Stopped sleep 300» и снова получите доступное приглашение командной строки, хотя сам процесс sleep» не завершился, а лишь «заморожен».
[Скриншот терминала]
Шаг 3. Проверьте список задач текущей сессии: `jobs».
Что вы увидите: строку с номером задачи (например, [1]), её текущим статусом («Stopped») и самой командой.
Шаг 4. Возобновите задачу в фоновом режиме: `bg».
Что произойдёт: приостановленный процесс `sleep» возобновит выполнение, но теперь уже в фоне, не блокируя терминал — вы снова сможете свободно вводить команды.
Шаг 5. Проверьте список задач ещё раз: `jobs» — статус задачи должен был измениться на «Running» (выполняется), в отличие от предыдущего «Stopped».
[Скриншот результата]
Шаг 6. Верните задачу обратно на передний план: fg» (без явного указания номера — по умолчанию возвращается самая последняя задача; при необходимости конкретный номер можно указать явно, например fg %1, используя номер, увиденный в выводе jobs`).
Что произойдёт: терминал снова «зависнет» в ожидании этой задачи, как это было изначально на шаге 1, до того как мы приостановили её сочетанием `Ctrl+Z».
Шаг 7. Прервите выполнение полностью сочетанием `Ctrl+C» (вспомните урок 4.5), так как нам не нужно реально дожидаться полных 300 секунд.
Шаг 8. Потренируем nohup». Запустите команду, полностью отвязанную от терминала, с перенаправлением вывода в файл (вспомните операторы перенаправления из Блока 6, так как при использовании nohup» вывод команды, если он не перенаправлен явно, обычно автоматически сохраняется в специальный файл nohup.out»): nohup sleep 60 > /dev/null 2>&1 &» (мы используем уже знакомую нам из Блока 6 конструкцию для полного подавления вывода, чтобы не создавать лишний файл `nohup.out» в рамках этой простой учебной демонстрации).
Что произойдёт: команда запустится в фоне, отвязанная от терминала — в реальной практике это означает, что даже если вы полностью закроете это окно терминала, процесс продолжит спокойно работать в системе (мы не будем проверять это буквальным закрытием терминала в рамках данной практики, но важно понимать именно эту практическую особенность nohup).
Разбор команд
Символ &
- Назначение:** запускает команду сразу в фоновом режиме.
- Синтаксис:** `команда &»
Команда jobs
- Назначение:** показывает список фоновых и приостановленных задач текущей сессии терминала.
- Синтаксис:**
jobs [опции]
Команды bg/fg
- Назначение:**
bg» возобновляет приостановленную задачу в фоне;fg» возвращает фоновую или приостановленную задачу на передний план. - Синтаксис:**
bg [%номер_задачи]/fg [%номер_задачи]
Команда nohup
- Назначение:** запускает команду так, чтобы она продолжала работать даже после закрытия родительского терминала.
- Синтаксис:**
nohup команда &» (обычно используется вместе с&`, чтобы дополнительно ещё и не блокировать текущий терминал во время работы). - Реальные примеры использования:** `nohup python3 long_running_script.py > output.log 2>&1 &» — характерный пример запуска долго работающего скрипта (тема Блока 15) на сервере через SSH-соединение (тема Блока 13), которое впоследствии может быть закрыто, но сам скрипт при этом должен продолжать работать.
- Типичные ошибки:** ожидание, что обычная фоновая задача (просто через
&», безnohup) переживёт закрытие родительского терминала — как мы уже разобрали в теории, это не так, если явно не использован именноnohup».
Возможные ошибки
- Ошибка:** закрытие терминала с активной, важной фоновой задачей, запущенной без
nohup, в ожидании, что она продолжит работать самостоятельно.
Почему возникает: непонимание разницы между «фоновым режимом внутри текущей сессии» (&») и «полной отвязкой от родительского процесса» (nohup`).
Как определить: после переоткрытия терминала (или переподключения по SSH) обнаруживается, что задача, которая должна была продолжать работать, на самом деле неожиданно прервалась вместе с закрытием предыдущей сессии.
Как исправить: заново запустить нужную задачу, на этот раз явно используя `nohup», если действительно требуется, чтобы она пережила закрытие сессии терминала.
Как избежать: для любых по-настоящему долго работающих задач, которые должны продолжать выполнение независимо от состояния текущей сессии терминала (особенно актуально при удалённой работе через SSH, тема Блока 13), с самого начала использовать nohup» вместо простого &».
Практические задания
- Повторите полный цикл
Ctrl+Z→jobs→bg→jobs→fgсамостоятельно на новой тестовой задачеsleep, без подглядывания в инструкцию. - Запустите одновременно две разные фоновые задачи (например,
sleep 100 &» иsleep 200 &»), проверьте выводjobs», убедившись, что видите обе задачи с разными номерами, и завершите обе задачи, используя изученную в предыдущем уроке командуkill», найдя их PID черезjobs -l» (параметр-l`, list, дополнительно показывает и PID рядом с номером задачи, а не только сам номер). - Своими словами объясните в конспекте разницу между простой фоновой задачей (
&») и задачей, запущенной черезnohup`, применительно к ситуации закрытия терминала.
Проверка знаний
Вопрос 1. Что происходит с обычной фоновой задачей (запущенной просто через &, без nohup), если закрыть терминал, в котором она была запущена?
Ответ: Как правило, она тоже автоматически завершается вместе с закрытием родительской сессии терминала, так как остаётся дочерним процессом этой сессии, несмотря на формальную работу «в фоне».
Вопрос 2. Чем отличается Ctrl+Z» от Ctrl+C» применительно к текущей выполняющейся команде?
Ответ: Ctrl+C» полностью прерывает (завершает) выполнение текущей команды. Ctrl+Z» лишь приостанавливает её выполнение (аналогично сигналу SIGSTOP), не завершая — приостановленную таким образом задачу впоследствии можно возобновить командами bg» или fg».
Итоги урока
Вы изучили: механизм фоновых и foreground-задач, команды jobs, bg, fg, `nohup», и различие между обычной фоновой задачей и задачей, полностью отвязанной от родительского терминала.
Вы умеете: приостанавливать, возобновлять и переключать задачи между фоновым и передним режимом выполнения, запускать по-настоящему независимые от сессии терминала процессы.
В следующем уроке потребуется: полное понимание процессов, чтобы разобраться в понятиях демона и службы — специальной категории долго работающих фоновых процессов, обеспечивающих работу системы.
Урок 10.5. Что такое демон (daemon) и служба (service)
Понять концепцию демонов и служб — специальной категории процессов, отвечающих за постоянную, фоновую работу ключевых компонентов системы, что подготовит почву для полноценного изучения systemd в следующем уроке.
Теория
Демон (daemon, произносится «дэймон» или, в русскоязычном сообществе, часто просто «демон») — это специальный тип процесса, разработанный для длительной, непрерывной работы в фоновом режиме, обычно без прямого взаимодействия с конкретным пользователем через терминал, и часто запускаемый автоматически при старте системы, ещё до входа какого-либо конкретного пользователя в систему. Название происходит от древнегреческого понятия «daimon» — в данном контексте используется в значении некоего невидимого, но полезного «духа-помощника», незаметно выполняющего свою работу в фоне (это не имеет негативной, зловещей коннотации, несмотря на созвучие с английским словом «demon» в другом написании).
По исторической конвенции UNIX/Linux, имена программ-демонов часто (хотя и не всегда строго обязательно) заканчиваются на букву d» — например, sshd» (демон службы SSH, тему которой подробно разберём в Блоке 13), crond» (демон планировщика задач, тему которого разберём чуть позже в этом же блоке), systemd» (сам центральный демон управления системой, о котором пойдёт речь в следующем уроке).
Служба (service) — это близкое по смыслу, хотя и не строго тождественное понятие: службой чаще называют функциональную единицу с точки зрения управления системой (то, что можно запустить, остановить, перезапустить, настроить автозапуск) — и очень часто конкретная служба реализуется именно через запуск соответствующего демона в качестве работающего процесса. На практике в современном Linux, особенно в контексте systemd (следующий урок), термины «служба» и «демон» часто используются как практически взаимозаменяемые, хотя концептуально «служба» — это скорее более общий, управленческий термин, а «демон» — конкретная техническая реализация в виде специфического типа процесса.
Примеры типичных служб/демонов, с некоторыми из которых мы уже сталкивались или ещё столкнёмся в курсе:
- служба SSH (
sshd) — обеспечивает возможность удалённого подключения к компьютеру (Блок 13); - служба веб-сервера (
nginx, тема Блока 19) — обрабатывает входящие запросы к сайтам; - служба системного журналирования (о ней подробно поговорим уже в этом блоке, урок 10.7) — собирает и сохраняет системные сообщения от других процессов;
- служба планировщика заданий (
cron, тему которой раскроем в этом же блоке) — запускает другие команды по расписанию.
Практика
Шаг 1. Найдём несколько работающих в вашей системе демонов через уже хорошо изученную в этом блоке команду ps aux, отфильтровав по характерному признаку имени, оканчивающемуся на d» (используя уже знакомый нам grep» с регулярным выражением из Блока 6): `ps aux | grep -E '[a-z]+d\s' | head -n 10» (это несколько упрощённый, ознакомительный пример регулярного выражения, ищущий слова, заканчивающиеся на «d» перед пробелом, — не претендующий на абсолютную техническую точность для всех случаев, но полезный для ознакомительной практики).
Что вы увидите: несколько строк с процессами, чьи имена действительно заканчиваются на `d», подтверждающих упомянутую в теории историческую конвенцию именования.
[Скриншот терминала]
Шаг 2. Найдём конкретно уже упомянутый в теории systemd», центральный демон управления системой, к которому подробно вернёмся в следующем уроке: ps aux | grep systemd | head -n 5».
Что вы увидите: несколько процессов, связанных с `systemd» — сам этот факт наглядно подтверждает, что даже центральная система управления в Linux технически реализована как набор обычных процессов, подчиняющихся всем изученным нами в этом блоке принципам (PID, иерархия, возможность отправки сигналов).
Шаг 3. Проверьте PID самого первого процесса в системе — того самого «корня» всего дерева процессов, о котором мы упоминали в уроке 10.1: ps -p 1» (параметр -p, process, позволяет запросить информацию о процессе с конкретным, явно указанным PID — а PID, равный 1`, зарезервирован именно за самым первым процессом, запускаемым ядром при загрузке).
Что вы увидите: скорее всего, именно `systemd» будет являться этим самым первым процессом в современной Ubuntu — подтверждение его центральной, фундаментальной роли, которую мы подробно раскроем в следующем уроке.
[Скриншот результата]
Разбор команд
Параметр -p команды ps
- Назначение:** показывает информацию о процессе с явно указанным, конкретным PID.
- Синтаксис:**
ps -p PID - Реальные примеры использования:** `ps -p 1» — узнать, какая именно программа является самым первым процессом системы (как мы только что практиковали).
Возможные ошибки
- Ошибка:** попытка напрямую взаимодействовать с демоном/службой через простое завершение соответствующего процесса командой `kill» (изученной в уроке 10.3), вместо использования штатных, специально предназначенных для этого средств управления службами.
Почему возникает: новичок ещё не знаком с более подходящим инструментом (systemctl», который подробно разберём уже в следующем уроке) и по инерции применяет уже знакомый ему kill».
Как определить: сложно определить сразу, но такой подход менее надёжен: многие демоны настроены на автоматический перезапуск при неожиданном завершении именно системой управления службами, и простое `kill» может привести к неожиданному, немедленному перезапуску процесса самой системой, либо, наоборот, оставить систему в неопределённом, не полностью корректном состоянии, не соответствующем ожиданиям штатного механизма управления.
Как исправить/избежать: для управления работой служб (запуск, остановка, перезапуск) всегда предпочитать штатный инструмент systemctl», который мы подробно изучим уже в следующем уроке, вместо прямого управления через сигналы и kill», оставляя последний способ для действительно исключительных ситуаций, когда штатные средства управления по какой-либо причине не срабатывают.
Практические задания
- Найдите в своей системе через `ps aux | grep -E '[a-z]+d\s'» пять разных процессов-демонов и запишите в конспект их имена вместе с предположением об их назначении, основываясь на самом имени (можно свериться с интернетом при затруднении).
- Проверьте PID процесса
systemd» черезps -p 1» и своими словами объясните в конспекте, почему именно этот процесс занимает такое особое, «первое» положение в иерархии всех процессов системы. - Своими словами (без подглядывания) объясните разницу между понятиями «демон» и «служба», как они были определены в теории этого урока.
Проверка знаний
Вопрос 1. Какая историческая конвенция именования часто (хотя и не всегда строго) применяется к именам программ-демонов в Linux?
Ответ: Их имена часто заканчиваются на букву d» (например, sshd, crond, systemd`), хотя это скорее устоявшаяся традиция, чем строгое техническое требование.
Вопрос 2. Какой PID зарезервирован за самым первым процессом системы, запускаемым непосредственно ядром при загрузке?
Ответ: PID, равный 1. В современной Ubuntu этим первым процессом обычно является systemd.
Итоги урока
Вы изучили: понятия демона и службы, их практическое соотношение друг с другом, и особую роль первого процесса системы с PID=1.
Вы умеете: находить процессы-демоны в системе и определять самый первый процесс через `ps -p 1».
В следующем уроке потребуется: это понимание, чтобы полноценно освоить systemd — центральную систему инициализации и управления службами в современном Ubuntu.
Урок 10.6. systemd: init-система, юниты, `systemctl`
Освоить systemd — центральную систему инициализации и управления службами в современном Ubuntu (и подавляющем большинстве других современных дистрибутивов Linux), и главный инструмент работы с ней — команду systemctl.
Теория
Мы уже несколько раз упоминали systemd» на протяжении курса (уроки 2.2, 10.5), но пришло время разобрать его полноценно. systemd` — это init-система (система инициализации) — тот самый первый процесс с PID=1, о котором мы говорили в предыдущем уроке, отвечающий за запуск, в правильном порядке и с учётом взаимных зависимостей, всех остальных процессов и служб системы при её загрузке, а также за дальнейшее управление ими на протяжении всего времени работы системы (запуск, остановка, перезапуск, автоматический перезапуск в случае сбоя, и так далее).
Важно отметить: systemd» — не единственная существующая в истории Linux init-система (более старая альтернатива, до широкого распространения systemd, называлась SysV init» — System V init, отсюда и историческое происхождение некоторых старых, хотя иногда всё ещё встречающихся, команд и конвенций), но именно `systemd» стал стандартом де-факто в подавляющем большинстве современных дистрибутивов, включая используемую нами Ubuntu, начиная с относительно ранних версий.
Основная единица управления в systemd» называется юнитом (unit). Существует несколько типов юнитов, но наиболее часто встречающийся и практически важный для нас — service unit (юнит службы), описывающий конкретную службу: как её запускать, от имени какого пользователя, при каких условиях автоматически перезапускать в случае сбоя, от каких других служб она зависит (то есть какие другие службы должны быть уже запущены раньше неё), и многое другое. Файлы описания юнитов обычно имеют расширение .service» и располагаются в системных папках, таких как /etc/systemd/system/» или /lib/systemd/system/» (мы подробно вернёмся к структуре и содержимому таких файлов уже практически, в Блоке 19, при настройке собственной службы).
systemctl — главная команда для взаимодействия с `systemd», позволяющая запускать, останавливать, перезапускать службы, проверять их текущий статус, и, что особенно важно для практического администрирования, включать и выключать их автоматический запуск при следующей загрузке системы.
Практика
Шаг 1. Проверьте статус какой-либо реально работающей в вашей системе службы — например, службы, отвечающей за системное журналирование (к которой мы подробно вернёмся уже в следующем уроке): `systemctl status systemd-journald».
Что вы увидите: подробную информацию о состоянии службы — активна ли она сейчас («active (running)»), включён ли её автоматический запуск при загрузке («enabled»), её PID, объём использованной памяти, и несколько последних строк из связанного с ней журнала (тему которого раскроем в следующем уроке).
[Скриншот терминала]
Шаг 2. Просмотрите полный список всех активных на данный момент юнитов служб в системе: `systemctl list-units --type=service».
Что вы увидите: длинный список всех работающих служб с кратким описанием состояния каждой.
Шаг 3. Проверьте статус SSH-службы (тема которой подробно раскроется в Блоке 13) — по умолчанию она может быть не установлена и не запущена в базовой установке Ubuntu Desktop (в отличие от версии Ubuntu Server, где она часто устанавливается сразу): `systemctl status ssh».
Что произойдёт: если служба не установлена, вы увидите соответствующее сообщение — это нормально для Ubuntu Desktop, к настройке SSH мы вернёмся отдельно, детально, в Блоке 13.
Шаг 4. Установим для практики службу, с которой мы будем плотно работать позже в курсе, но здесь используем просто в качестве безопасного и наглядного примера для тренировки systemctl» — веб-сервер Nginx (тема Блока 19), используя уже хорошо изученный APT из Блока 9: sudo apt update» и `sudo apt install nginx».
Что произойдёт: помимо самой установки пакета (уже привычной нам с Блока 9), APT также автоматически зарегистрирует соответствующий юнит службы в `systemd» и, как правило, сразу же автоматически запустит и включит его автозапуск — типичное, удобное поведение для многих серверных программ, устанавливаемых в Ubuntu.
Шаг 5. Проверьте статус только что установленной службы Nginx: `systemctl status nginx».
Что вы увидите: статус «active (running)», подтверждающий, что служба действительно уже автоматически запущена сразу после установки.
[Скриншот результата]
Шаг 6. Остановите службу: sudo systemctl stop nginx» (обратите внимание: изменение состояния служб, аналогично уже привычным нам операциям с apt, требует прав sudo`, в полном соответствии с материалом Блока 8).
Шаг 7. Проверьте статус ещё раз: `systemctl status nginx» — теперь должно отображаться «inactive (dead)».
Шаг 8. Запустите службу снова: `sudo systemctl start nginx».
Шаг 9. Потренируем перезапуск (частая практическая операция после изменения конфигурации службы, тему которой затронем подробнее в Блоке 19): `sudo systemctl restart nginx».
Шаг 10. Проверьте, включён ли автозапуск этой службы при загрузке системы: `systemctl is-enabled nginx».
Шаг 11. Потренируем отключение автозапуска (не останавливая при этом саму текущую работу службы): sudo systemctl disable nginx», а затем включим обратно: sudo systemctl enable nginx».
Разбор команд
Команда systemctl
- Назначение:** управление службами (юнитами) через systemd.
- Синтаксис:**
systemctl [подкоманда] [имя_службы] - Основные параметры:**
status имя» (показать текущий статус);start имя» (запустить);stop имя» (остановить);restart имя» (перезапустить — фактически последовательно stop, затем start);reload имя» (перечитать конфигурацию службы без полной остановки и повторного запуска, если сама служба это поддерживает — часто более «мягкий» и быстрый способ применить изменения конфигурации, чем полныйrestart);enable имя» (включить автозапуск при загрузке системы);disable имя» (выключить автозапуск);is-enabled имя» (проверить, включён ли автозапуск);is-active имя» (проверить, активна ли служба прямо сейчас, кратким, однословным ответом, удобным для использования в скриптах, тема которых будет подробно раскрыта в Блоке 15);list-units --type=service» (показать список всех служб). - Реальные примеры использования:** `sudo systemctl restart nginx» — стандартная практическая операция после изменения конфигурационного файла веб-сервера (детально разберём в Блоке 19), чтобы применить внесённые изменения.
- Типичные ошибки:** путаница между
start/stop» (текущее, немедленное состояние работы службы прямо сейчас) иenable/disable» (будет ли служба автоматически запущена при следующей загрузке системы) — это два независимых, ортогональных друг другу параметра: можно, например, включить автозапуск (enable), но при этом сейчас служба всё ещё может быть не запущена (stop), пока не будет либо явно запущена командойstart, либо система не будет перезагружена.
Как определить: неожиданное поведение — служба, которую вы «включили» (enable), не работает прямо сейчас, или, наоборот, служба, которую вы «выключили» (disable), продолжает работать до следующей перезагрузки.
Способы исправления: чётко разделять эти два разных действия и выполнять оба (start» и enable», либо stop» и disable`), если требуется и немедленный эффект, и правильное поведение при следующей загрузке.
Возможные ошибки
- Ошибка:** забыть добавить
sudo» перед командами, изменяющими состояние службы (start,stop,restart,enable,disable), в отличие от команд простого просмотра статуса (status,is-enabled`), которые обычно доступны без повышенных прав.
Как определить: сообщение об ошибке доступа при попытке выполнить изменяющую команду без `sudo».
Способы исправления: добавить `sudo» перед командой.
Как избежать: запомнить общее правило, уже знакомое нам по духу из Блока 8 и Блока 9 — любое действие, изменяющее состояние всей системы (а не только просматривающее информацию), как правило, требует `sudo».
Практические задания
- Найдите (через
systemctl list-units --type=service) три любые работающие службы в вашей системе и проверьте подробный статус каждой из них через `systemctl status», записав в конспект краткое предположение об их назначении. - Повторите полный цикл
stop→status→start→restart→disable→is-enabled→enable→is-enabledдля установленной службы Nginx самостоятельно, без подглядывания в инструкцию практики этого урока. - Своими словами (не подглядывая) объясните в конспекте разницу между
systemctl stop» иsystemctl disable», приведя пример ситуации, где может понадобиться выполнить только одно из этих двух действий, но не оба сразу.
Проверка знаний
Вопрос 1. В чём разница между systemctl stop имя и systemctl disable имя?
Ответ: stop» немедленно останавливает уже работающую службу прямо сейчас, но не влияет на её поведение при следующей перезагрузке системы (если автозапуск включён, служба снова запустится). disable» отключает автоматический запуск службы при следующей загрузке системы, но не влияет на её текущее состояние работы прямо сейчас (если служба уже была запущена, она продолжит работать до явной остановки или перезагрузки).
Вопрос 2. Как называется основная единица управления в systemd, описывающая, например, конкретную службу?
Ответ: Юнит (unit), точнее в случае службы — service unit (юнит службы), обычно описываемый файлом с расширением `.service».
Итоги урока
Вы изучили: понятие systemd как init-системы, концепцию юнитов служб, и полный набор команд `systemctl» для управления жизненным циклом и автозапуском служб.
Вы умеете: проверять статус, запускать, останавливать, перезапускать службы и управлять их автозапуском при загрузке системы.
В следующем уроке потребуется: это понимание служб, чтобы научиться читать связанные с ними системные журналы через `journalctl», центральный инструмент диагностики проблем со службами.
Урок 10.7. Журналы systemd: `journalctl`
Освоить journalctl — центральный инструмент просмотра системных журналов в современных дистрибутивах на базе systemd, критически важный для диагностики проблем со службами, который мы будем активно применять и в Блоке 18, посвящённом мониторингу и troubleshooting.
Теория
Мы уже касались темы журналов (логов) в уроке 5.2 (папка /var/log) и уроке 6.4 (tail -f), но в современных дистрибутивах на базе systemd, включая Ubuntu, значительная часть системных журналов дополнительно хранится в специальном, структурированном, бинарном (не обычном текстовом) формате, управляемом отдельным компонентом systemd — journald (обратите внимание на уже знакомое нам по предыдущему уроку окончание «d», указывающее на демон). Это тот самый systemd-journald, статус которого мы уже проверяли в практике предыдущего урока.
Почему используется именно бинарный, структурированный формат вместо простого текста, к которому мы уже привыкли работать через cat/grep/tail» из Блока 6? Такой формат позволяет хранить значительно больше метаданных о каждой записи журнала (не только сам текст сообщения, но и точное время с высокой точностью, идентификатор процесса-источника, приоритет/важность сообщения, и многое другое), а также обеспечивает более эффективную и гибкую фильтрацию при просмотре — именно для этого и предназначена специальная команда journalctl`, а не универсальные текстовые инструменты Блока 6, которые попросту не смогли бы напрямую работать с этим особым бинарным форматом хранения.
Важно отметить: journalctl» не заменяет полностью классические текстовые журналы в /var/log» (многие программы, особенно не столь тесно интегрированные с systemd, по-прежнему продолжают писать свои журналы именно в привычном текстовом формате в эту папку, и там по-прежнему прекрасно работают все уже изученные нами в Блоке 6 инструменты) — скорее, `journalctl» дополняет их, предоставляя централизованный, единообразный способ просмотра журналов именно тех служб и компонентов, которые интегрированы с systemd и используют его систему журналирования.
Практика
Шаг 1. Просмотрите общий, полный журнал системы (может быть очень длинным, поэтому команда автоматически открывается в уже знакомом нам с Блока 6 постраничном режиме просмотра, аналогичном less): `journalctl».
Что вы увидите: хронологический список системных сообщений от множества различных служб и компонентов, начиная с самого раннего сохранённого момента.
[Скриншот терминала]
Шаг 2. Выйдите из просмотра (клавиша q, аналогично уже знакомому нам поведению less/man), и просмотрите журнал, отфильтрованный именно по конкретной, интересующей вас службе, используя параметр -u» (unit): journalctl -u nginx» (используя уже установленную в предыдущем уроке службу Nginx).
Что вы увидите: только те записи журнала, которые относятся именно к службе Nginx — например, сообщения о её запуске, остановке, и возможные предупреждения или ошибки, если они возникали.
Шаг 3. Просмотрите только самые последние записи, аналогично уже знакомой нам по Блоку 6 команде tail, используя параметр -n: `journalctl -u nginx -n 20» (последние 20 записей).
Шаг 4. Потренируем режим реального времени, концептуально аналогичный уже знакомому нам tail -f» из Блока 6, но встроенный прямо в journalctl» через параметр -f: `journalctl -u nginx -f».
Что произойдёт: терминал перейдёт в режим ожидания новых записей журнала, связанных именно со службой Nginx, обновляясь в реальном времени по мере их появления — аналогично `tail -f», но уже применительно к структурированному журналу systemd, а не к обычному текстовому файлу.
Шаг 5. Откройте второй, отдельный терминал (как мы уже практиковали в предыдущих блоках) и перезапустите службу Nginx: `sudo systemctl restart nginx».
Шаг 6. Вернитесь к первому терминалу, где выполняется `journalctl -f» — вы должны увидеть новые записи журнала, связанные с только что произошедшим перезапуском, появившиеся автоматически, в реальном времени.
[Скриншот результата]
Шаг 7. Прервите режим реального времени сочетанием Ctrl+C» (аналогично тому, как мы уже прерывали tail -f» в Блоке 6).
Шаг 8. Отфильтруйте журнал по времени, используя параметр --since, чтобы увидеть только события за последний час: `journalctl --since "1 hour ago"».
Разбор команд
Команда journalctl
- Назначение:** просмотр структурированных системных журналов, управляемых systemd-journald.
- Синтаксис:**
journalctl [опции] - Основные параметры:**
-u имя_службы» (фильтр по конкретной службе);-f» (режим реального времени, follow, аналогичноtail -f);-n число» (показать только последние N записей);--since "время"» и--until "время"» (фильтр по временному диапазону, поддерживает как точные даты, так и удобные относительные выражения вроде «1 hour ago», «yesterday»);-p приоритет» (фильтр по уровню важности сообщения, например `-p err» покажет только сообщения об ошибках и более серьёзные). - Реальные примеры использования:** `journalctl -u nginx --since "10 minutes ago"» — характерный пример при диагностике только что возникшей проблемы (тема Блока 18) — быстро посмотреть, что происходило со службой за последние несколько минут, не пролистывая весь потенциально огромный общий журнал.
- Типичные ошибки:** попытка просматривать
journalctl» без учёта, что по умолчанию открывается постраничный режим просмотра (аналогичноless`), и растерянность относительно того, как из него выйти.
Способы исправления: клавиша `q», аналогично уже знакомому поведению из предыдущих блоков.
Возможные ошибки
- Ошибка:** попытка найти в
journalctl» журнал программы, которая на самом деле не интегрирована с системой journald и продолжает писать логи по старинке, в обычном текстовом файле где-то в/var/log».
Почему возникает: новичок предполагает, что абсолютно все системные журналы теперь централизованно доступны через единый `journalctl», не разграничивая программы по степени их интеграции с systemd.
Как определить: команда `journalctl -u имя_программы» не находит никаких записей, хотя вы точно знаете, что программа активно работает и генерирует какие-то сообщения.
Как исправить: поискать классический текстовый файл журнала этой конкретной программы в /var/log» (часто в отдельной подпапке, названной по имени самой программы) и применить к нему уже хорошо знакомые нам из Блока 6 инструменты (tail -f, grep`, и другие).
Как избежать: воспринимать journalctl» и классические текстовые журналы в /var/log» как два дополняющих друг друга, а не полностью взаимоисключающих подхода, и при необходимости проверять оба места при диагностике конкретной, незнакомой программы.
Практические задания
- Просмотрите журнал только что установленной в предыдущем уроке службы Nginx (
journalctl -u nginx) и найдите в нём запись о самом первом запуске службы сразу после установки. - Используя параметр
--since, просмотрите общий системный журнал за последние 30 минут и опишите в конспекте, какие типы событий вы там обнаружили. - Потренируйте режим реального времени
journalctl -u nginx -f» ещё раз, но на этот раз, находясь во втором терминале, не просто перезапустите службу, а сначала остановите её (stop), затем запустите заново (start`) отдельными командами, и понаблюдайте, как оба события — остановка и последующий запуск — по отдельности появляются в журнале в реальном времени.
Проверка знаний
Вопрос 1. Зачем systemd использует специальный бинарный формат хранения журналов вместо простого текста, к которому мы уже привыкли из Блока 6?
Ответ: Бинарный, структурированный формат позволяет хранить больше метаданных о каждой записи (точное время, идентификатор процесса, приоритет сообщения) и обеспечивает более эффективную и гибкую фильтрацию при просмотре через специальную команду `journalctl», чего сложнее добиться при работе с обычным неструктурированным текстом.
Вопрос 2. Заменяет ли journalctl полностью классические текстовые журналы в папке /var/log?
Ответ: Нет, не заменяет полностью. Многие программы, не столь тесно интегрированные с systemd, продолжают писать свои журналы в классическом текстовом формате именно в /var/log, и оба подхода (structured journalctl и классические текстовые логи) сосуществуют, дополняя друг друга.
Итоги урока
Вы изучили: концепцию structured-журналирования через systemd-journald и полный набор возможностей команды `journalctl» для фильтрации по службе, времени и режиму реального времени.
Вы умеете: просматривать и фильтровать системные журналы, отслеживать события служб в реальном времени.
В следующем уроке потребуется: понимание процессов и служб, чтобы освоить планировщик задач `cron», позволяющий автоматически запускать команды по заданному расписанию.
Урок 10.8. Планировщик задач `cron` и `crontab`
Освоить cron — классический, широко распространённый инструмент планирования регулярно повторяющихся задач в Linux, который станет незаменимым помощником в автоматизации (Блок 15), особенно для регулярного резервного копирования (Блок 11) и других периодических административных операций.
Теория
cron — это демон (вспомните уже знакомую нам по уроку 10.5 конвенцию именования — соответствующий демон часто называется именно crond, хотя команда для взаимодействия с настройками называется просто cron/crontab), который постоянно работает в фоне и в заданное расписанием время автоматически запускает указанные команды или скрипты, без необходимости какого-либо ручного вмешательства пользователя в этот конкретный момент.
Расписание для `cron» задаётся в специальном, стандартизированном, хотя и не самом интуитивном на первый взгляд формате — пять полей, разделённых пробелами, каждое из которых отвечает за отдельную временную единицу:
```
минута час день_месяца месяц день_недели команда
```
- Минута**: от 0 до 59.
- Час**: от 0 до 23 (в 24-часовом формате).
- День месяца**: от 1 до 31.
- Месяц**: от 1 до 12.
- День недели**: от 0 до 7 (и 0, и 7 означают воскресенье — историческая особенность, унаследованная от разных конвенций в разных старых системах).
Специальный символ » (звёздочка, аналогичная по духу уже знакомому нам символу-шаблону из Блока 5, хотя здесь она несёт немного иной, специфичный именно для cron смысл) в любом из этих пяти полей означает «каждое значение», то есть «без ограничения по этому конкретному параметру». Например, расписание 0 3 » означает «в 0 минут 3 часа, каждый день месяца, каждый месяц, каждый день недели» — то есть попросту «каждый день ровно в 3:00 ночи».
Каждый пользователь системы может иметь свой собственный, отдельный список запланированных задач — crontab (сокращение от «cron table», «таблица cron»), редактируемый специальной командой crontab -e», которая открывает соответствующий файл в текстовом редакторе по умолчанию (напоминающем нам об уже изученной в Блоке 6 переменной $EDITOR» и об инструментах Блока 7).
Практика
Шаг 1. Просмотрите текущий (скорее всего, пока пустой) список запланированных задач вашего пользователя: `crontab -l» (list) — если задач ещё нет, вы, вероятно, увидите сообщение вида «no crontab for [username]», что совершенно нормально для только что установленной, ещё не настроенной системы.
Шаг 2. Откройте редактор crontab для добавления новой задачи: `crontab -e» (при первом запуске система может попросить вас выбрать предпочитаемый текстовый редактор из предложенного списка — рекомендуется выбрать уже хорошо знакомый нам по Блоку 7 nano, если он предложен как один из вариантов, для более простой и привычной практики).
[Скриншот терминала]
Шаг 3. Добавьте в конец открывшегося файла (обычно там уже присутствуют комментарии с краткой справкой по формату, начинающиеся с уже знакомого нам по Блоку 6 символа #) тестовую строку, которая будет каждую минуту дописывать текущую дату в тестовый файл в вашей учебной папке — что позволит нам быстро, буквально за пару минут, увидеть результат работы cron, не дожидаясь долгого реального расписания вроде «раз в сутки»: * echo "Cron сработал: $(date)" >> ~/Linux-Course/Block-10/cron_test.txt» (обратите внимание на уже знакомую нам из уроков 5.6 и 8.9 конструкцию $(...)» — подстановку команды, в данном случае подставляющую результат вызова уже хорошо знакомой нам команды `date» прямо внутрь текста, записываемого в файл).
Шаг 4. Сохраните файл и выйдите из редактора (для nano — уже знакомое нам сочетание Ctrl+O, Enter, `Ctrl+X» из Блока 7).
Что произойдёт: после сохранения система автоматически применит обновлённое расписание, без необходимости какого-либо дополнительного перезапуска.
Шаг 5. Подождите одну-две минуты (реальное время ожидания, так как мы настроили запуск именно каждую минуту), а затем проверьте результат: `cat ~/Linux-Course/Block-10/cron_test.txt».
Что вы увидите: одну или несколько строк с текущей датой и временем на момент каждого срабатывания cron — наглядное практическое подтверждение того, что автоматический запуск действительно происходит, без какого-либо ручного вмешательства с вашей стороны.
[Скриншот результата]
Шаг 6. Удалите тестовую задачу, чтобы она не продолжала бесконечно работать каждую минуту после завершения практики этого урока: снова откройте `crontab -e», удалите добавленную на шаге 3 строку (используя уже хорошо знакомые нам навыки редактирования из Блока 7), сохраните и закройте файл.
Шаг 7. Проверьте более практически реалистичный, характерный пример расписания — «каждый день в 3:30 ночи» — и попробуйте самостоятельно, без подглядывания, составить для него правильную пятиполевую строку cron (не добавляя её реально в crontab, просто в качестве упражнения на бумаге или в конспекте), сверяя свой результат с теорией этого урока после самостоятельной попытки.
Разбор команд
Команда crontab
- Назначение:** управление персональным списком запланированных задач пользователя.
- Синтаксис:**
crontab [опции] - Основные параметры:**
-e» (edit, открыть редактор для изменения списка задач);-l» (list, показать текущий список задач);-r» (remove, полностью удалить весь список задач текущего пользователя — используется реже, так как обычно удобнее удалять отдельные, конкретные строки через-e`, а не сразу весь список целиком). - Реальные примеры использования:*
0 2/home/student/backup_script.sh» (в файле, открытом через crontab -e`) — характерный пример реальной задачи, запускающей собственный скрипт резервного копирования (тема Блока 11 и Блока 15) каждый день ровно в 2 часа ночи, когда система обычно наименее загружена активной пользовательской работой. - Типичные ошибки:** ошибки в синтаксисе пятиполевого расписания, например перепутанный порядок полей (минута/час вместо ожидаемого час/минута).
Как определить: задача либо не запускается вообще, либо запускается в неожиданное время, отличное от предполагаемого.
Способы исправления: внимательно перепроверить порядок полей, сверяясь с теорией этого урока (минута → час → день месяца → месяц → день недели), и при затруднениях воспользоваться одним из множества доступных онлайн-инструментов для визуальной проверки корректности расписания cron (хотя для целей этого курса вполне достаточно уверенного ручного составления расписаний, основанного на изученной теории).
Возможные ошибки
- Ошибка:** забыть удалить тестовую или отладочную задачу с чрезмерно частым расписанием (как наш пример «каждую минуту» из практики), из-за чего она продолжает бесконечно работать в фоне, даже после того как реальная необходимость в ней уже прошла.
Почему возникает: тестовые задачи с намеренно частым расписанием удобны именно для быстрой проверки работоспособности во время обучения или отладки, но легко забываются впоследствии.
Как определить: неожиданно накапливающиеся файлы или записи в журналах (тема предыдущего урока про journalctl», хотя классический cron», строго говоря, чаще пишет свои собственные логи в традиционный /var/log, а не через journalctl напрямую — в зависимости от конкретной настройки конкретной системы), не соответствующие ожидаемой, значительно более редкой частоте.
Как исправить: проверить весь список активных задач через `crontab -l» и удалить любые более ненужные, особенно частые тестовые записи.
Как избежать: сразу после завершения тестирования любой временной, отладочной задачи cron — не откладывая, сразу же её удалять, как мы и практиковали на шаге 6 данного урока.
Практические задания
- Повторите полный цикл добавления, проверки срабатывания и последующего удаления тестовой задачи cron самостоятельно, используя другой, отличный от практики урока, простой тестовый пример (например, вывод не даты, а любого другого простого сообщения).
- Самостоятельно составьте (без выполнения, просто как письменное упражнение в конспекте) правильные пятиполевые расписания cron для следующих трёх ситуаций: «каждый понедельник в 9 утра», «каждые 15 минут» (подсказка: изучите специальный синтаксис
*/15» для полей минут, слегка выходящий за рамки базовой теории этого урока, — попробуйте разобраться в его логике самостоятельно черезman crontab`, вспомнив урок 4.7), «первого числа каждого месяца в полночь». - Своими словами объясните в конспекте, почему для действительно регулярных, длительных задач (например, ежедневного резервного копирования)
cronпредпочтительнее, чем, скажем, вручную запускать нужную команду каждый раз, когда вы об этом вспоминаете.
Проверка знаний
Вопрос 1. Что означает символ * в любом из пяти полей расписания cron?
Ответ: Он означает «каждое значение» этого конкретного временного поля, то есть отсутствие ограничения именно по этому параметру — например, звёздочка в поле «день недели» означает «в любой день недели», не ограничивая расписание конкретными днями.
Вопрос 2. Какая команда используется для открытия текстового редактора с целью добавления, изменения или удаления запланированных задач текущего пользователя?
Ответ: `crontab -e».
Итоги урока
Вы изучили: концепцию cron как планировщика регулярно повторяющихся задач, синтаксис пятиполевого расписания, и команду `crontab» с её основными параметрами.
Вы умеете: добавлять, просматривать и удалять запланированные задачи cron, составлять корректные расписания для типичных практических ситуаций.
В следующем уроке потребуется: понимание регулярного планирования через cron, чтобы освоить похожий, но концептуально отличающийся инструмент — at, предназначенный именно для разовых, а не повторяющихся задач.
Урок 10.9. Разовые задачи: `at`
Освоить команду at — инструмент для планирования выполнения команды ровно один раз в заданный момент времени в будущем, дополняющий уже изученный в предыдущем уроке cron, предназначенный именно для регулярно повторяющихся задач.
Теория
В предыдущем уроке мы изучили cron» — инструмент для регулярно повторяющихся задач (каждый день, каждую неделю, каждый месяц, и так далее). Но что делать, если требуется выполнить команду лишь один-единственный раз, в конкретный момент времени в будущем, без необходимости настройки и последующей очистки полноценного регулярного расписания cron? Именно эту, более узкую и специфическую задачу решает команда **at`».
Синтаксис at заметно отличается от cron: вместо строгого пятиполевого формата, `at» принимает время в значительно более гибком, «человекочитаемом» формате — можно указать точное время («10:30 PM»), относительное время от текущего момента («now + 1 hour», то есть «через час от текущего момента»), или даже конкретную дату («10:30 PM July 25»).
После указания времени команда at» открывает специальный интерактивный режим ввода, в котором вы построчно вводите одну или несколько команд, которые должны быть выполнены в указанный момент, и завершаете ввод специальным сочетанием клавиш Ctrl+D» (End Of File, «конец файла» — специальная, стандартная для многих UNIX-программ комбинация, сигнализирующая программе, что ввод данных пользователем полностью завершён; мы ещё вернёмся к этому важному сочетанию клавиш в Блоке 15, при работе с более сложными Bash-конструкциями).
В отличие от cron», который в базовой установке Ubuntu обычно предустановлен и сразу готов к работе, at» часто требует отдельной, дополнительной установки через уже хорошо знакомый нам с Блока 9 APT.
Практика
Шаг 1. Проверьте, установлен ли at в вашей системе: `which at» (используя уже знакомую нам команду из Блока 5).
Шаг 2. Если команда не найдена — установите её: sudo apt update» и sudo apt install at».
Что произойдёт: помимо самой команды at, будет установлена и запущена соответствующая служба `atd» (снова обратите внимание на уже знакомое нам окончание «d» в названии — вспомните урок 10.5), отвечающая за фактическое отслеживание времени и запуск запланированных разовых задач.
[Скриншот терминала]
Шаг 3. Запланируйте тестовую задачу на две минуты вперёд от текущего момента: `at now + 2 minutes».
Что произойдёт: терминал перейдёт в специальный интерактивный режим ввода команд, обычно с приглашением вида `at>».
Шаг 4. Введите команду, которая должна быть выполнена (аналогично тестовому примеру из предыдущего урока про cron): `echo "Задача at сработала: $(date)" >> ~/Linux-Course/Block-10/at_test.txt».
Шаг 5. Нажмите Enter, чтобы перейти на новую строку внутри всё того же интерактивного режима at (можно ввести и несколько последовательных команд подряд, если требуется — каждая на своей отдельной строке), а затем нажмите Ctrl+D, чтобы полностью завершить ввод и подтвердить создание отложенной задачи.
Что вы увидите: подтверждающее сообщение с указанием номера задания (job number, концептуально похожего, хотя и технически отдельного от уже знакомых нам номеров фоновых задач из урока 10.4) и точного времени, на которое оно запланировано.
[Скриншот настроек]
Шаг 6. Проверьте список всех ожидающих выполнения отложенных задач at» (аналогично тому, как мы проверяли список задач cron): atq» (at queue, «очередь at»).
Что вы увидите: строку с номером вашего задания и запланированным временем его выполнения.
Шаг 7. Подождите чуть больше двух минут, а затем проверьте результат: `cat ~/Linux-Course/Block-10/at_test.txt».
Что вы увидите: строку с датой и временем — подтверждение, что отложенная разовая задача действительно была автоматически выполнена в нужный момент.
[Скриншот результата]
Шаг 8. Потренируйте отмену запланированной, но ещё не выполненной задачи. Запланируйте новую тестовую задачу на значительно более отдалённое время (например, at now + 1 hour, повторив шаги 3-5 с другим временным интервалом и любой безопасной тестовой командой), проверьте её номер через atq, а затем отмените её командой atrm», указав соответствующий номер задания: atrm номер_задания».
Шаг 9. Проверьте список ещё раз через `atq», чтобы убедиться, что отменённая задача действительно больше не значится в очереди на выполнение.
Разбор команд
Команда at
- Назначение:** планирует выполнение одной или нескольких команд ровно один раз в указанный момент времени в будущем.
- Синтаксис:**
at время_выполнения» (после чего следует интерактивный ввод команд, завершаемыйCtrl+D`) - Реальные примеры использования:** `at 6:00 AM tomorrow» — характерный пример разового напоминания или разовой административной операции (например, однократный, заранее спланированный перезапуск определённой службы в заведомо малозагруженное время), для которой не требуется постоянное, регулярное расписание, в отличие от типичных задач cron.
Команда atq
- Назначение:** показывает список всех запланированных, но ещё не выполненных задач `at» текущего пользователя.
- Синтаксис:** `atq»
Команда atrm
- Назначение:** отменяет (удаляет) конкретную запланированную задачу `at» по её номеру.
- Синтаксис:** `atrm номер_задания»
Возможные ошибки
- Ошибка:** попытка использовать
at» для регулярно повторяющейся задачи, вместо более подходящего для этой целиcron», что привело бы к необходимости вручную, заново, каждый раз создавать новую отложенную задачу `at» после выполнения предыдущей.
Почему возникает: недостаточно чёткое разграничение в понимании между двумя изученными в этом блоке инструментами (cron для регулярных задач, `at» для одноразовых).
Как определить: повторяющаяся необходимость каждый раз заново вручную создавать одну и ту же отложенную задачу.
Как исправить: переключиться на использование crontab -e» для настройки действительно регулярного, повторяющегося расписания вместо повторного создания разовых задач at».
Как избежать: чётко запомнить это разграничение с самого начала: cron — для «каждый день/неделю/месяц», `at» — для «один-единственный раз в конкретный момент времени».
Практические задания
- Повторите полный цикл создания, проверки через
atq, ожидания выполнения и проверки результата тестовой задачи `at» самостоятельно, используя другой, отличный от практики урока, временной интервал и тестовую команду. - Запланируйте задачу с использованием более далёкого, конкретного времени (не относительного «now + X», а абсолютного, например, «10:00 PM» с сегодняшней или завтрашней датой, в зависимости от текущего времени на момент выполнения задания) и проверьте её появление в очереди через
atq», не дожидаясь реального времени выполнения — сразу же отмените её черезatrm» для завершения этого учебного упражнения. - Составьте в конспекте краткую сравнительную таблицу
cron» иat» по критериям: тип задачи (регулярная/разовая), формат указания времени, основная команда для добавления новой задачи, команда для просмотра текущего списка.
Проверка знаний
Вопрос 1. В чём принципиальное отличие at от cron с точки зрения типа задач, для которых предназначен каждый из этих инструментов?
Ответ: cron предназначен для регулярно, циклически повторяющихся задач (например, каждый день или каждую неделю). `at» предназначен для выполнения команды ровно один раз, в конкретный, заданный момент времени в будущем, без последующего повторения.
Вопрос 2. Каким сочетанием клавиш завершается интерактивный ввод команд после вызова at время?
Ответ: `Ctrl+D» (End Of File) — стандартное для многих UNIX-программ сочетание, сигнализирующее о завершении ввода данных пользователем.
Итоги урока
Вы изучили: назначение команды at» как инструмента для одноразовых отложенных задач, синтаксис указания времени выполнения, команды atq» и `atrm» для просмотра и отмены запланированных задач.
Вы умеете: планировать, просматривать и отменять одноразовые отложенные задачи, чётко отличая ситуации, где уместнее at, от ситуаций, требующих полноценного `cron».
В следующем уроке (это будет уже Блок 11) потребуется: весь накопленный в этом блоке материал о процессах и автоматизации по расписанию, чтобы применить его к теме дисков, файловых систем и особенно резервного копирования, где регулярные задачи cron найдут одно из своих самых практически важных применений.
Мини-проект блока
Задача: создать и настроить собственную, простую systemd-службу, закрепив весь материал этого блока о процессах, службах и systemd на практике.
Что нужно сделать:
- Создайте простой Bash-скрипт (используя уже изученные в Блоке 7 текстовые редакторы; полноценно синтаксис Bash-скриптов мы изучим только в Блоке 15, поэтому здесь достаточно простого скрипта из одной-двух строк, например периодически дописывающего текущую дату в файл в бесконечном цикле с паузой, — можно взять за основу конструкцию
while true; do date >> ~/Linux-Course/Block-10/service_test.log; sleep 10; done, слегка забегая вперёд по синтаксису циклов, который будет подробно раскрыт позже, но уже вполне понятной по аналогии с примерами этого блока). - Сделайте этот скрипт исполняемым, используя уже хорошо знакомую команду `chmod +x» из Блока 8.
- Создайте файл описания systemd-юнита для этого скрипта в
/etc/systemd/system/» (потребуетсяsudoи один из уже изученных текстовых редакторов; базовая структура файла.service» обычно включает разделы[Unit],[Service]с указанием пути к вашему скрипту черезExecStart=, и[Install]— попробуйте найти актуальный минимальный пример структуры такого файла через поиск в интернете или официальную документацию, слегка выходя за рамки прямого материала уроков этого блока, в качестве самостоятельного исследовательского упражнения). - Перезагрузите конфигурацию systemd, чтобы она обнаружила новый юнит:
sudo systemctl daemon-reload» (эта команда не была подробно разобрана в уроках, но упоминается здесь как необходимый практический шаг — попробуйте разобраться в её назначении самостоятельно, посмотревman systemctl`). - Запустите новую службу и включите её автозапуск, используя уже хорошо знакомые команды
systemctl start» иsystemctl enable». - Проверьте её статус и содержимое связанного с ней журнала через `journalctl -u».
- Остановите и отключите автозапуск службы по завершении практики, чтобы она не продолжала работать в фоне после мини-проекта.
Критерий готовности: служба успешно создана, запускается, её работа подтверждается содержимым тестового лог-файла и записями в журнале, автозапуск корректно включается и выключается.
Контрольные вопросы
- Объясните разницу между процессом и программой, а также понятия PID и PPID.
- В чём разница между
ps,topиhtop? - Опишите разницу между сигналами SIGTERM и SIGKILL, и почему рекомендуется сначала пробовать первый.
- Что произойдёт с обычной фоновой задачей (
&) при закрытии терминала, и как этого избежать? - Что такое юнит в systemd, и какая команда используется для управления службами?
- В чём разница между
systemctl stopиsystemctl disable? - Составьте расписание cron для задачи «каждый рабочий будний день в 18:00» (подсказка: используйте диапазон в поле дня недели).
- Чем
atпринципиально отличается отcronпо назначению?
Выводы по блоку
В этом блоке вы освоили полную картину того, как Linux управляет работающими программами — от базового понятия процесса и его места в иерархии, через инструменты мониторинга и управления (ps, top, htop, kill), фоновые задачи, демоны и службы, к центральной системе управления современного Linux — systemd, и завершили блок инструментами автоматического планирования задач — cron и `at». Этот материал станет фундаментом для понимания того, как работают серверные программы в последующих блоках курса (Docker в Блоке 17, Nginx и базы данных в Блоке 19), а также прямой подготовкой к автоматизации через Bash-скрипты в Блоке 15.
Список изученных тем
- Понятия процесса, PID, PPID, иерархии процессов.
- Инструменты просмотра процессов:
ps,top,htop. - Сигналы и управление процессами:
kill,killall,nice/renice. - Фоновые и foreground-задачи:
&,jobs,bg,fg,nohup. - Демоны и службы, их соотношение друг с другом.
- systemd: init-система, юниты, команда
systemctl. - Журналы systemd:
journalctlс фильтрацией по службе, времени, режимом реального времени. - Планировщик регулярных задач
cron» иcrontab`. - Планировщик разовых задач
at»,atq», `atrm».
Рекомендации перед переходом
Убедитесь, что вы уверенно владеете полным циклом управления службой через systemctl» (status, start, stop, restart, enable, disable») и можете составить корректное расписание cron для типичной практической задачи. Этот материал будет активно применяться уже в следующем блоке при настройке автоматического резервного копирования по расписанию, а также в дальнейших блоках курса при работе с Docker, Nginx и базами данных — все эти технологии в Linux управляются именно через systemd, и уверенное владение материалом этого блока сделает работу с ними значительно более понятной.