Введение
Работающая система Linux — это не только файлы. Ядро управляет оборудованием и процессами, каждая команда выполняется как процесс со своим идентификатором, а оболочка отслеживает задания, выполняемые на переднем и заднем плане. Администратор сначала изучает текущее состояние системы, а затем воздействует на минимально необходимый процесс.
В этой лабораторной работе вы определите операционную систему и версию ядра, проанализируете время работы и средние значения нагрузки, изучите взаимосвязи между процессами, найдёте процессы по имени, отправите сигналы завершения, попрактикуетесь в интерактивном управлении заданиями, интерпретируете коды завершения, запустите автономную команду с помощью nohup и прочитаете последние сообщения ядра.
Определение системы и интерпретация нагрузки
На этом этапе вы определите ядро и дистрибутив, проверите продолжительность работы системы и узнаете, что означают средние значения нагрузки.
Создайте рабочий каталог и перейдите в него:
mkdir -p /home/labex/project/process-lab
cd /home/labex/project/process-lab
Команда uname выводит сведения о ядре. Параметры -s, -r и -m выбирают имя ядра, его версию и архитектуру машины:
uname -srm
uname -a отображает все доступные поля в одной строке:
uname -a
Ядро — это не то же самое, что дистрибутив Linux. Прочитайте метаданные дистрибутива:
cat /etc/os-release
Обратите внимание на такие поля, как NAME, VERSION и ID. Затем проверьте время работы системы и нагрузку:
uptime
В выводе отображаются текущее время, продолжительность работы системы, количество вошедших пользователей и три средних значения нагрузки. Эти значения описывают объём готовой к выполнению или непрерываемой работы примерно за 1, 5 и 15 минут. Это не проценты: их интерпретация частично зависит от количества ядер процессора.
Просмотрите компактную запись нагрузки, хранящуюся в ядре:
cat /proc/loadavg
Первые три значения соответствуют средним значениям нагрузки. Последующие поля показывают количество готовых к выполнению задач и недавно назначенный идентификатор процесса.
Сохраните краткую сводку о системе для дальнейшего использования:
uname -srm > system-summary.txt
uptime >> system-summary.txt
cat system-summary.txt
Файл должен содержать одну строку со сведениями о ядре и одну строку с информацией о времени работы системы.
Анализ процессов и активности ресурсов
На этом этапе вы изучите идентификаторы процессов, связи между родительскими и дочерними процессами, их состояния, а также снимок активности системных ресурсов.
Процесс — это выполняемая программа. У каждого процесса есть идентификатор процесса, или PID. У большинства процессов также имеется идентификатор родительского процесса, или PPID, указывающий на процесс, который их запустил.
Команда ps отображает снимок процессов. Выберите полезные поля и отсортируйте их по PID:
cd /home/labex/project/process-lab
ps -eo pid,ppid,user,stat,comm --sort=pid | head -n 15
Параметр -e выбирает все процессы, а -o задаёт столбцы:
PID— идентификатор процесса.PPID— идентификатор родительского процесса.USER— владелец процесса.STAT— состояние процесса и дополнительные флаги.COMMAND— имя исполняемого файла.
К распространённым обозначениям состояний относятся R для выполняющегося процесса, S для прерываемого сна, D для непрерываемого сна, T для остановленного процесса и Z для процесса-зомби. Процесс в состоянии сна чаще всего просто ожидает работы.
Форма ps aux в BSD-стиле дополнительно выводит столбцы загрузки процессора и использования памяти, а также полные командные строки:
ps aux | head -n 10
При интерактивном использовании top непрерывно обновляет данные. Пакетный режим позволяет получить один стабильный снимок: -b выбирает пакетный вывод, а -n 1 запрашивает одно обновление.
top -b -n 1 | head -n 12
В заголовке приводятся сведения о времени работы, нагрузке, состояниях задач, использовании процессора и памяти. Таблица процессов ниже помогает найти наиболее активно использующие ресурсы процессы.
Теперь откройте интерактивное представление:
top
Проследите за обновлением значений, найдите столбцы %CPU и %MEM, затем нажмите q, чтобы вернуться в оболочку. Интерактивный режим top удобен для наблюдения за изменениями во времени; пакетный режим лучше подходит, когда вывод нужно сохранить или обработать другой командой.
Сохраните сфокусированный снимок процессов как результат наблюдения:
ps -eo pid,ppid,user,stat,comm --sort=pid > process-snapshot.txt
head -n 5 process-snapshot.txt
Запуск и поиск тестового процесса
На этом этапе вы запустите безвредный фоновый процесс, сохраните его PID и найдёте его с помощью ps и pgrep.
Символ & в конце команды указывает оболочке выполнить её в фоне и сразу вернуть приглашение. Запустите процесс сна продолжительностью пять минут с отображаемым именем labex-worker:
cd /home/labex/project/process-lab
bash -c 'exec -a labex-worker sleep 300' &
Специальное значение оболочки $! содержит PID последнего запущенного фонового процесса. Сохраните его до запуска другой фоновой команды:
worker_pid=$!
echo "$worker_pid" > worker.pid
Проверьте именно этот процесс. Параметр -p выбирает PID, а -o задаёт поля:
ps -o pid,ppid,user,stat,etime,args -p "$worker_pid"
ETIME показывает прошедшее время работы, а ARGS содержит отображаемое имя процесса. Используйте pgrep -f для поиска по полной командной строке; параметр -a также выводит её:
pgrep -af labex-worker
PID, найденный с помощью pgrep, должен совпадать со значением в worker.pid. Поиск по точному шаблону безопаснее, чем воздействие на все процессы с общим именем.
Завершение процессов с помощью сигналов
На этом этапе вы запросите корректное завершение с помощью SIGTERM и примените SIGKILL только к процессу, специально настроенному игнорировать этот сигнал.
Команда kill отправляет сигнал указанному PID. Если сигнал явно не задан, отправляется SIGTERM, сигнал 15. SIGTERM запрашивает корректное завершение и даёт процессу возможность освободить ресурсы и выполнить очистку.
Прочитайте PID рабочего процесса и отправьте SIGTERM:
cd /home/labex/project/process-lab
worker_pid=$(cat worker.pid)
kill "$worker_pid"
sleep 1
Следующая ожидаемая ошибка команды ps подтверждает, что процесс завершился:
ps -p "$worker_pid" || echo "labex-worker stopped after SIGTERM"
Теперь запустите управляемый процесс, который намеренно игнорирует SIGTERM:
bash -c 'trap "" TERM; exec -a labex-stubborn sleep 300' &
stubborn_pid=$!
echo "$stubborn_pid" > stubborn.pid
Дайте новой оболочке немного времени на установку обработчика сигнала:
sleep 1
Отправьте SIGTERM, немного подождите и проверьте процесс:
kill -TERM "$stubborn_pid"
sleep 1
ps -o pid,stat,args -p "$stubborn_pid"
Процесс по-прежнему должен присутствовать, поскольку он игнорирует SIGTERM. SIGKILL, сигнал 9, невозможно перехватить или проигнорировать. Используйте его только после того, как корректный сигнал не дал результата:
kill -KILL "$stubborn_pid"
Дождитесь завершения фонового задания. Ненулевой код завершения ожидаем, поэтому || true позволяет продолжить последовательность упражнений:
wait "$stubborn_pid" 2>/dev/null || true
ps -p "$stubborn_pid" || echo "labex-stubborn required SIGKILL"
SIGKILL не даёт процессу возможности сохранить состояние или корректно освободить ресурсы приложения, поэтому это крайняя мера.
kill обращается к известному PID. Если нужно выбрать процесс по имени или полной командной строке, pkill объединяет сопоставление и отправку сигнала. Запустите ещё один контролируемый процесс с отличительной командной строкой:
bash -c 'exec -a labex-helper sleep 300' &
helper_pid=$!
echo "$helper_pid" > helper.pid
Перед выполнением действия подтвердите точное совпадение полной командной строки:
pgrep -af '^labex-helper 300$'
Отправьте SIGTERM этому точному совпадению с помощью pkill -f. Якоря ^ и $ не позволяют учебному шаблону совпасть с посторонними командными строками:
pkill -TERM -f '^labex-helper 300$'
wait "$helper_pid" 2>/dev/null || true
ps -p "$helper_pid" || echo "labex-helper stopped by pkill"
Используйте точные шаблоны pkill и сначала проверяйте совпадения с помощью pgrep: слишком широкий шаблон может остановить больше процессов, чем планировалось.
Управление заданиями на переднем и заднем плане
На этом этапе вы приостановите команду, выполняемую на переднем плане, возобновите её в фоне, вернёте на передний план и прервёте её.
Управление заданиями относится к текущей интерактивной оболочке. Запустите на переднем плане процесс сна с узнаваемым именем:
cd /home/labex/project/process-lab
bash -c 'exec -a labex-job sleep 300'
Теперь терминал занят процессом переднего плана. Нажмите Ctrl+Z. Оболочка отправит сигнал остановки и вернёт приглашение.
Выведите список заданий, известных этой оболочке. Параметр -l добавляет идентификатор процесса:
jobs -l
Вы должны увидеть задание в состоянии Stopped. Возобновите задание номер 1 в фоновом режиме:
bg %1
jobs -l
Теперь состояние должно быть Running, а приглашение должно оставаться доступным. Верните задание на передний план:
fg %1
Нажмите Ctrl+C, чтобы отправить сигнал прерывания заданию на переднем плане. Приглашение должно появиться снова. Убедитесь, что тестовое задание не осталось:
pgrep -af labex-job || echo "No labex-job process remains"
После завершения интерактивной последовательности создайте маркер:
touch job-control.done
Используйте управление заданиями для команд, привязанных к текущему терминалу. Позже вы примените nohup для задач, которые не должны зависеть от сеанса терминала.
Чтение кода завершения и запуск автономной задачи
На этом этапе вы интерпретируете коды завершения команд и запустите короткую фоновую задачу, вывод которой сохранится независимо от отображения в терминале.
Каждая команда возвращает целочисленный код завершения. Ноль означает успешное выполнение, ненулевое значение — ошибку какого-либо типа. Переменная оболочки $? содержит код завершения последней завершившейся команды.
Выполните успешную команду и сразу выведите её код завершения:
cd /home/labex/project/process-lab
true
echo "true status: $?"
Результат равен 0. Теперь выполните команду, которая не сможет найти указанный путь:
ls missing-path
Сохраните её код завершения до того, как другая команда изменит $?:
missing_status=$?
echo "missing-path status: $missing_status"
Значение будет ненулевым. Сохраните обе ожидаемые интерпретации:
printf 'success=0\nfailure=%s\n' "$missing_status" > exit-status.txt
Команда nohup заставляет программу игнорировать сигнал разрыва терминала. Последний & запускает её в фоне. Перенаправление < /dev/null отключает ввод с терминала, а > nohup.log 2>&1 направляет оба потока вывода в журнал:
nohup bash -c 'for item in one two three; do echo "background: $item"; sleep 1; done' < /dev/null > nohup.log 2>&1 &
Сохраните PID фонового процесса и дождитесь завершения короткой задачи:
echo $! > nohup.pid
sleep 4
cat nohup.log
Вы должны увидеть три строки — от background: one до background: three. Для длительных задач сохранённые PID и журнал позволяют отслеживать ход выполнения.
Просмотр последних сообщений ядра
На этом этапе вы изучите буфер сообщений ядра и сохраните версию работающего ядра в качестве стабильной справочной информации.
Ядро записывает в кольцевой буфер сообщения о запуске системы, оборудовании, драйверах и событиях во время работы. Команда dmesg читает этот буфер. Обычно для её выполнения нужны административные права:
cd /home/labex/project/process-lab
sudo dmesg | tail -n 10
Конкретные сообщения зависят от машины и времени. Обратите внимание на поле, похожее на временную отметку, а также на компонент или подсистему, сформировавшие каждое сообщение.
Параметр --level фильтрует сообщения по уровню важности. Выведите последние предупреждения и ошибки:
sudo dmesg --level=err,warn | tail -n 10
Отсутствие вывода не означает, что команда завершилась с ошибкой: возможно, в текущем буфере нет сообщений соответствующих уровней. Выполните поиск распространённых терминов, связанных с накопителями и сетью:
sudo dmesg | grep -Ei 'disk|filesystem|network|eth' | tail -n 10
Результат снова зависит от текущего состояния системы. Сохраните версию ядра, возвращаемую uname -r:
uname -r > kernel-version.txt
cat kernel-version.txt
Сообщения ядра — это фактические данные, а не готовый диагноз. Прежде чем принимать решение, сопоставьте их с состоянием процессов, журналами служб и наблюдаемыми симптомами.
Итоги
Вы идентифицировали систему Linux, проанализировали время работы и средние значения нагрузки, а также изучили идентификаторы процессов, их родительские процессы, владельцев, состояния и снимки использования ресурсов. Вы запустили и нашли процесс с заданным именем, применили SIGTERM до SIGKILL и попрактиковались в управлении заданиями на переднем и заднем плане.
Кроме того, вы интерпретировали коды завершения, запустили автономную задачу с помощью nohup и явного журналирования, а также изучили сообщения ядра с помощью dmesg. Такой подход, основанный прежде всего на наблюдении, является основой безопасной диагностики проблем с процессами и подготовит вас к дальнейшей работе со службами, журналами и сетевой диагностикой.



