← Назад к вопросам

Как завершить процесс в Ubuntu?

2.0 Middle🔥 111 комментариев
#Linux

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Завершение процессов в Ubuntu: полное руководство для QA Automation Engineer

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

Основные методы завершения процессов

1. Определение PID (Process ID)

Перед завершением нужно идентифицировать процесс. Основные инструменты:

# Поиск по имени процесса
ps aux | grep firefox

# Более современный и удобный вариант
pgrep firefox

# Поиск с выводом полной информации
pidof firefox

В автоматизации я часто комбинирую эти команды для надежности:

# Получаем PID и сразу проверяем существование процесса
PID=$(pgrep -f "my_test_service")
if [ -n "$PID" ]; then
    echo "Процесс найден с PID: $PID"
fi

2. Завершение с помощью kill и его вариаций

kill — базовый инструмент, но важно понимать типы сигналов:

# Корректное завершение (SIGTERM, сигнал 15) - просит процесс завершиться
kill PID
# или явно
kill -15 PID

# Безусловное завершение (SIGKILL, сигнал 9) - немедленная остановка
kill -9 PID

# Отправка сигнала HUP (часто используется для перезагрузки конфигов)
kill -1 PID

pkill — завершение по имени процесса (удобно в скриптах):

# Завершить все процессы firefox
pkill firefox

# С опцией -f для поиска по полной командной строке
pkill -f "python test_suite.py"

killall — аналогично pkill, но с другим синтаксисом:

# Завершить все процессы с именем chrome
killall chrome

# С определенным сигналом
killall -9 java

Практические сценарии в автоматизации тестирования

Сценарий 1: Очистка перед запуском тестов

Часто нужно гарантировать "чистое" состояние системы:

#!/bin/bash
# Скрипт предварительной очистки для тестов

echo "Останавливаем тестовые сервисы..."

# Завершаем старые экземпляры Selenium/браузеров
pkill -f "chromedriver"
pkill -f "geckodriver"
pkill -f "Xvfb"  # виртуальный дисплей для headless-тестов

# Ждем завершения корректных процессов
sleep 2

# Принудительно завершаем оставшиеся
pkill -9 -f "chromedriver"
pkill -9 -f "geckodriver"

# Проверяем, что процессы завершены
if pgrep -f "chromedriver" > /dev/null; then
    echo "ОШИБКА: chromedriver все еще работает!"
    exit 1
fi

Сценарий 2: Завершение процессов по таймауту

В автоматизации часто нужен graceful shutdown с последующим force kill:

#!/bin/bash
PROCESS_NAME="my_app"
TIMEOUT=10

# Ищем PID
PID=$(pgrep -f "$PROCESS_NAME")

if [ -z "$PID" ]; then
    echo "Процесс $PROCESS_NAME не найден"
    exit 0
fi

echo "Отправляем SIGTERM процессу $PID"
kill -15 "$PID"

# Ждем graceful завершения
for i in $(seq 1 $TIMEOUT); do
    if ! ps -p "$PID" > /dev/null; then
        echo "Процесс завершился корректно"
        exit 0
    fi
    sleep 1
done

# Если не завершился - убиваем принудительно
echo "Таймаут истекал, отправляем SIGKILL"
kill -9 "$PID"

Продвинутые техники для QA Automation

Завершение целых групп процессов

Часто тестовый процесс порождает дочерние процессы:

# Завершаем всю process group
kill -- -$(ps -o pgid= $PID | grep -o '[0-9]*')

# Или через pkill с опцией -P для родительского PID
pkill -P $PARENT_PID

Использование timeout для контроля выполнения

Утилита timeout — элегантное решение для контроля времени выполнения:

# Запускаем тесты с лимитом времени 5 минут
timeout 300 ./run_tests.sh

# С определенным сигналом (по умолчанию SIGTERM, потом SIGKILL)
timeout -k 30 300 ./run_tests.sh  # Через 300 сек SIGTERM, через 30 сек SIGKILL

Безопасность и лучшие практики

  1. Всегда сначала пытайтесь использовать SIGTERM — это позволяет процессу корректно освободить ресурсы
  2. SIGKILL — последнее средство, так как процесс не может его обработать
  3. В скриптах проверяйте существование процесса перед попыткой завершения
  4. Используйте wait для ожидания завершения дочерних процессов
  5. Логируйте действия с процессами для отладки

Интеграция с Python-скриптами автоматизации

В Python-фреймворках можно использовать subprocess и psutil:

import psutil
import subprocess
import signal
import time

def kill_process_tree(pid):
    """Корректное завершение дерева процессов"""
    try:
        parent = psutil.Process(pid)
        children = parent.children(recursive=True)
        
        # Завершаем дочерние процессы
        for child in children:
            child.terminate()
        
        # Ждем завершения
        gone, alive = psutil.wait_procs(children, timeout=5)
        
        # Принудительно завершаем оставшиеся
        for child in alive:
            child.kill()
        
        # Завершаем родительский процесс
        parent.terminate()
        parent.wait(5)
        
    except psutil.NoSuchProcess:
        pass

Для автоматизатора ключевое — не просто знание команд, а понимание, когда и какую стратегию завершения применять. В CI/CD пайплайнах я предпочитаю многоуровневый подход: сначала корректное завершение, затем принудительное с таймаутами, и всегда с валидацией результата.