Linux EPERMВысокая

Ошибка 'Operation not permitted' при kill в Linux: причины и решения

Статья объясняет, почему команда kill может завершиться ошибкой EPERM в Linux, и предлагает проверенные способы решения проблемы — от проверки прав до работы с uninterruptible sleep.

Обновлено 17 февраля 2026 г.
5-10 мин
Низкая
FixPedia Team
Применимо к:Linux ядро 4.x+Ubuntu 20.04+CentOS 7+Debian 10+

Что означает ошибка "kill: (PID) - Operation not permitted"

Эта ошибка соответствует коду EPERM (Operation not permitted) и появляется, когда процесс kill не может отправить сигнал указанному процессу. Полный текст обычно выглядит так:

kill: (1234) - Operation not permitted

Ошибка означает, что ядро Linux отклонил запрос на отправку сигнала (например, SIGTERM или SIGKILL). Это происходит не из-за опечатки в PID, а из-за системных ограничений: недостатка прав, особого состояния процесса или политик безопасности.

Причины возникновения

  1. Недостаточно прав — вы пытаетесь завершить процесс, принадлежащий другому пользователю (например, root), без использования sudo.
  2. Процесс в uninterruptible sleep (D-состояние) — процесс ожидает завершения системного вывода (часто ввода-вывода к устройству) и игнорирует все сигналы, включая SIGKILL.
  3. Зомби-процесс (zombie) — процесс уже завершён, но его запись в таблице процессов не удалена, так как родитель не прочитал статус. Зомби не могут быть убиты.
  4. Политики безопасности — SELinux, AppArmor или Linux capabilities могут запрещать завершение определённых процессов (например, системных служб).
  5. Критичные системные процессы — попытка убить init (PID 1) или другие процессы, управляемые ядром, будет отклонена.

Способы решения

Способ 1: Проверьте права и используйте sudo

Самая частая причина — отсутствие прав. Убедитесь, что процесс не принадлежит другому пользователю:

ps -o user= -p <PID>

Если пользователь не вы, завершите процесс с sudo:

sudo kill <PID>
# Или принудительно
sudo kill -9 <PID>

⚠️ Важно: Сигнал SIGKILL (-9) должен использоваться только если SIGTERM (стандартный kill) не сработал, так как он не даёт процессу chance на корректное завершение.

Способ 2: Определите состояние процесса

Проверьте, не находится ли процесс в uninterruptible sleep (D-состояние):

ps -o stat= -p <PID>

Если в выводе есть буква D (например, D+), процесс в uninterruptible sleep. Такие процессы обычно ждут ответа от драйвера устройства (диск, NFS, сетевой интерфейс). Они не реагируют на SIGKILL.

Что делать для D-процессов:

  1. Узнайте, какой ресурс блокирует процесс, через strace (может потребовать sudo):
    sudo strace -p <PID> 2>&1 | grep -i "EAGAIN\|ETIMEDOUT\|NFS"
    
  2. Если процесс завис из-за NFS, попробуйте принудительно размонтировать файловую систему:
    sudo umount -l /точка/монтирования
    
  3. Если процесс связан с диском (например, ksoftirqd), возможно, проблема в драйвере или аппаратуре. В крайнем случае — перезагрузите систему.

Способ 3: Очистите зомби-процессы

Зомби-процессы отображаются в ps с состоянием Z:

ps aux | grep '^.* Z .*'

Зомби не потребляют CPU или память, но занимают запись в таблице процессов. Их нельзя убить — нужно завершить родительский процесс (PPID):

  1. Найдите PPID зомби:
    ps -o ppid= -p <ZombiePID>
    
  2. Завершите родительский процесс (осторожно, это может повлиять на другие дочерние процессы):
    sudo kill -9 <PPID>
    
    Или перезапустите службу, если это системный процесс:
    sudo systemctl restart <service-name>
    

Способ 4: Проверьте SELinux и AppArmor

Политики безопасности могут блокировать завершение процессов, особенно если они относятся к защищённым доменам (например, httpd_t для Apache).

Для SELinux:

  1. Временно переведите в permissive-режим (логирует, но не блокирует):
    sudo setenforce 0
    
  2. Попробуйте завершить процесс снова. Если сработало, настройте политику:
    sudo audit2allow -M mypol < /var/log/audit/audit.log
    sudo semodule -i mypol.pp
    
  3. Верните enforcing-режим:
    sudo setenforce 1
    

Для AppArmor:

  1. Проверьте, есть ли профиль для процесса:
    sudo apparmor_status | grep <имя_процесса>
    
  2. Временно отключите профиль:
    sudo apparmor_parser -R /etc/apparmor.d/usr.bin.<процесс>
    
  3. Если проблема исчезла, отредактируйте профиль, добавив разрешение на сигналы.

Способ 5: Используйте /proc для принудительного завершения (крайний случай)

Если процесс игнорирует все сигналы (редко, но возможно при ошибках в ядре), можно попробовать "убить" его через файловую систему /proc:

echo 1 > /proc/<PID>/coredump_filter 2>/dev/null
echo 9 > /proc/<PID>/signal 2>/dev/null

⚠️ Экспериментальный метод. Может привести к нестабильности системы. Используйте только если другие способы не помогли и перезагрузка невозможна.

Профилактика

  • Корректно завершайте процессы — используйте сначала SIGTERM (стандартный kill), затем SIGKILL. Это даёт процессу chance на сохранение данных.
  • Мониторинг D-состояний — регулярно проверяйте процессы в состоянии D через top (нажмите D для сортировки) или ps aux | grep '^.* D .*'. Частые D-процессы могут указывать на проблемы с оборудованием или драйверами.
  • Настройка родительских процессов — для служб под systemd убедитесь, что PIDFile указан корректно, а KillMode установлен в control-group (по умолчанию). Для кастомных скриптов — всегда обрабатывайте SIGCHLD и вызывайте wait().
  • Обновляйте ядро и драйверы — многие проблемы с uninterruptible sleep исправляются в обновлениях.
  • Осторожно с NFS — при монтировании удалённых файловых систем используйте опции soft и timeo, чтобы процессы не зависали навсегда при потере связи.

Часто задаваемые вопросы

Почему kill -9 не работает, хотя я запускаю его от root?
Что такое uninterruptible sleep (D-состояние) и как с ним бороться?
Как предотвратить появление зомби-процессов?
Может ли SELinux/AppArmor вызывать эту ошибку?

Полезное

Определите PID процесса и проверьте его состояние
Попробуйте завершить процесс с правами root
Обработайте процессы в D-состоянии
Очистите зомби-процессы
Проверьте политики безопасности (SELinux/AppArmor)

Эта статья помогла вам решить проблему?