SystemdDoctor
мешает работе сигналы оболочка вывод

signal=PIPE (status=13/PIPE) в systemd

PIPE приходит, когда программа пишет в канал или сокет, у которого другая сторона уже закрылась. У служб это обычно следствие устройства запуска: конвейер из двух команд, где вторая завершилась раньше, либо оборванное соединение, которое программа не обрабатывает.

Что это значит

Важная деталь: systemd по умолчанию игнорирует этот сигнал для запускаемых процессов, потому что параметр IgnoreSIGPIPE= включён. Если служба всё-таки умирает от PIPE, значит она сама вернула обработку сигнала себе или сигнал получил дочерний процесс, запущенный через оболочку.

Вероятные причины

По порядку: сверху то, что встречается чаще.

  1. В строке запуска собран конвейер через оболочку

    При ExecStart=/bin/sh -c "prog | grep ..." завершение правой части рвёт канал, и левая получает PIPE. Служба выглядит упавшей, хотя дело в устройстве команды.

  2. Программа не обрабатывает разрыв соединения

    Клиент отключился, а служба продолжила писать в сокет. Корректные сетевые службы это учитывают, самодельные — не всегда.

  3. Вывод направлен в программу, которая завершилась

    При StandardOutput=fd: или выводе в сторонний обработчик его завершение оставляет службу с закрытым каналом.

Диагностика

Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.

Показывает, не собран ли запуск через конвейер оболочки.

systemctl cat myapp.service

Обрабатывается ли сигнал и куда идёт вывод.

systemctl show myapp.service -p IgnoreSIGPIPE -p StandardOutput

Решение

Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.

1. В строке запуска собран конвейер через оболочку
Почему происходит
При ExecStart=/bin/sh -c "prog | grep ..." завершение правой части рвёт канал, и левая получает PIPE. Служба выглядит упавшей, хотя дело в устройстве команды.
Как проверить
Посмотрите строку запуска.
systemctl cat myapp.service | grep -E "^Exec"
Как исправить
Уберите конвейер: пусть программа пишет в журнал напрямую, а фильтрация делается при чтении через journalctl -g. Если конвейер нужен, оберните его в скрипт, который сам обрабатывает разрыв.
2. Программа не обрабатывает разрыв соединения
Почему происходит
Клиент отключился, а служба продолжила писать в сокет. Корректные сетевые службы это учитывают, самодельные — не всегда.
Как проверить
Посмотрите, что происходило перед падением, и есть ли в журнале строки про клиентов.
journalctl -u myapp.service -n 40 --no-pager
Как исправить
В программе следует игнорировать этот сигнал и обрабатывать ошибку записи. Как временная мера помогает IgnoreSIGPIPE=yes, если параметр был отключён.
3. Вывод направлен в программу, которая завершилась
Почему происходит
При StandardOutput=fd: или выводе в сторонний обработчик его завершение оставляет службу с закрытым каналом.
Как проверить
Посмотрите настройку вывода.
systemctl show myapp.service -p StandardOutput -p StandardError -p IgnoreSIGPIPE
Как исправить
Переведите вывод в журнал (StandardOutput=journal): его приёмник всегда на месте.

Пример вывода

Конвейер в строке запуска: правая часть завершилась первой. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.

× myapp.service - My application
     Active: failed (Result: signal) since Mon 2026-09-15 16:30:07 MSK; 1s ago
    Process: 16700 ExecStart=/bin/sh -c /usr/local/bin/myapp | head -100 (code=killed, signal=PIPE)

systemd[1]: myapp.service: Main process exited, code=killed, status=13/PIPE
systemd[1]: myapp.service: Failed with result 'signal'.

Связанные ошибки

  • status=203/EXEC в systemd Код 203/EXEC означает, что systemd не смог выполнить программу из ExecStart=. Разбор причин: путь, права, интерпретатор, синтаксис оболочки.
  • Failed with result 'signal' Состояние signal: процесс службы завершён сигналом без сохранения дампа. Как узнать, каким сигналом и от кого.
  • status=209/STDOUT в systemd Код 209/STDOUT: systemd не смог настроить стандартный вывод службы. Чаще всего виноват путь в StandardOutput=append: или file:.
  • Broken pipe в журнале службы Запись в закрытый канал или соединение: клиент отключился, обработчик завершился, конвейер разорван.
  • signal=ABRT (status=6/ABRT) в systemd Процесс службы завершён сигналом ABRT: программа сама прервала работу после внутренней проверки. Где искать причину.
  • signal=BUS (status=7/BUS) в systemd Процесс службы завершён сигналом BUS: ошибка доступа к памяти, часто из-за усечённого файла в отображении или заполненного диска.
  • signal=FPE (status=8/FPE) в systemd Процесс службы завершён сигналом FPE: арифметическая ошибка, чаще всего деление на ноль в целочисленной арифметике.
  • signal=HUP (status=1/HUP) в systemd Процесс службы завершён сигналом HUP. Обычно это перезагрузка настроек, которую программа поняла как команду выйти.

Источники

  • systemd.exec(5)
    IgnoreSIGPIPE= и обработка этого сигнала в процессах службы.
    официальная документация, systemd 255
    сверено 15 сентября 2026
  • Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
    Воспроизведено на unit с конвейером в ExecStart через sh -c.
    собственная проверка, systemd 255
    сверено 15 сентября 2026