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

Ответ от нейросети

sobes.tech AI

Long Killer – пользовательский скрипт в системе Unix/Linux, предназначенный для поиска и принудительного завершения процессов, работающих дольше заданного времени. Обычно используется для управления ресурсами и предотвращения зависания системы. Может быть реализован на различных скриптовых языках, таких как Bash или Python.

Принцип работы:

  1. Определение списка запущенных процессов (например, с помощью ps).
  2. Фильтрация процессов по различным критериям (пользователь, имя команды и т.д.).
  3. Определение длительности работы каждого интересующего процесса.
  4. Сравнение длительности работы с предопределенным пороговым значением.
  5. Отправка сигнала завершения (например, SIGTERM или SIGKILL) процессам, превысившим порог.

Пример реализации на Bash:

#!/bin/bash

# Пороговое время в секундах
THRESHOLD_SECONDS=3600 # 1 час

# Имя процесса для поиска. Оставьте пустым '', если нужно искать все процессы пользователя
PROCESS_NAME=""

# Пользователь, от имени которого запущены процессы. Оставьте пустым '', если нужно искать процессы всех пользователей
USER=""

# Исключить процессы по имени (разделенные пробелом)
EXCLUDE_PROCESSES="sshd bash long_killer.sh"

# Получаем список процессов, их время работы (ET), PID, имя команды и пользователя
ps -eo etime,pid,cmd,user --no-headers | while read ET PID CMD USER_NAME; do
    # Преобразуем время работы в секунды
    SECS=0
    if [[ "$ET" =~ ([0-9]+)-([0-9]+):([0-9]+):([0-9]+) ]]; then # Дни-часы:минуты:секунды
        SECS=$(( ${BASH_REMATCH[1]}*86400 + ${BASH_REMATCH[2]}*3600 + ${BASH_REMATCH[3]}*60 + ${BASH_REMATCH[4]} ))
    elif [[ "$ET" =~ ([0-9]+):([0-9]+):([0-9]+) ]]; then # Часы:минуты:секунды
        SECS=$(( ${BASH_REMATCH[1]}*3600 + ${BASH_REMATCH[2]}*60 + ${BASH_REMATCH[3]} ))
    elif [[ "$ET" =~ ([0-9]+):([0-9]+) ]]; then # Минуты:секунды
        SECS=$(( ${BASH_REMATCH[1]}*60 + ${BASH_REMATCH[2]} ))
    elif [[ "$ET" =~ ([0-9]+) ]]; then # Секунды
        SECS=${BASH_REMATCH[1]}
    fi

    # Проверяем условия для завершения
    KILL=false
    if [ "$SECS" -gt "$THRESHOLD_SECONDS" ]; then
        KILL=true
    fi

    if [ -n "$PROCESS_NAME" ] && [[ ! "$CMD" =~ "$PROCESS_NAME" ]]; then
        KILL=false
    fi

    if [ -n "$USER" ] && [ "$USER_NAME" != "$USER" ]; then
        KILL=false
    fi

    # Проверяем список исключений
    for EXCLUDE in $EXCLUDE_PROCESSES; do
        if [[ "$CMD" == *"$EXCLUDE"* ]]; then
            KILL=false
            break
        fi
    done

    # Завершаем процесс, если все условия выполнены и это не текущий скрипт
    if [ "$KILL" = true ] && [ "$PID" != "$$" ]; then
        echo "Killing process $PID ($CMD) running for $ET"
        kill $PID # Можно использовать kill -9 $PID для принудительного завершения
    fi
done

Этот скрипт можно запускать по расписанию, например, через Crontab.

# Запускать каждую минуту
* * * * * /path/to/your/long_killer.sh >> /var/log/long_killer.log 2>&1

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