signal=PIPE (status=13/PIPE) в systemd
PIPE приходит, когда программа пишет в канал или сокет, у которого другая сторона уже закрылась. У служб это обычно следствие устройства запуска: конвейер из двух команд, где вторая завершилась раньше, либо оборванное соединение, которое программа не обрабатывает.
Что это значит
Важная деталь: systemd по умолчанию игнорирует этот сигнал для запускаемых процессов, потому что параметр IgnoreSIGPIPE= включён. Если служба всё-таки умирает от PIPE, значит она сама вернула обработку сигнала себе или сигнал получил дочерний процесс, запущенный через оболочку.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
В строке запуска собран конвейер через оболочку
При
ExecStart=/bin/sh -c "prog | grep ..."завершение правой части рвёт канал, и левая получает PIPE. Служба выглядит упавшей, хотя дело в устройстве команды. -
Программа не обрабатывает разрыв соединения
Клиент отключился, а служба продолжила писать в сокет. Корректные сетевые службы это учитывают, самодельные — не всегда.
-
Вывод направлен в программу, которая завершилась
При
StandardOutput=fd:или выводе в сторонний обработчик его завершение оставляет службу с закрытым каналом.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Показывает, не собран ли запуск через конвейер оболочки.
systemctl cat myapp.serviceОбрабатывается ли сигнал и куда идёт вывод.
systemctl show myapp.service -p IgnoreSIGPIPE -p StandardOutputРешение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- При
ExecStart=/bin/sh -c "prog | grep ..."завершение правой части рвёт канал, и левая получает PIPE. Служба выглядит упавшей, хотя дело в устройстве команды.
- Как проверить
-
Посмотрите строку запуска.
systemctl cat myapp.service | grep -E "^Exec"
- Как исправить
-
Уберите конвейер: пусть программа пишет в журнал напрямую, а фильтрация делается при чтении через
journalctl -g. Если конвейер нужен, оберните его в скрипт, который сам обрабатывает разрыв.
- Почему происходит
- Клиент отключился, а служба продолжила писать в сокет. Корректные сетевые службы это учитывают, самодельные — не всегда.
- Как проверить
-
Посмотрите, что происходило перед падением, и есть ли в журнале строки про клиентов.
journalctl -u myapp.service -n 40 --no-pager
- Как исправить
-
В программе следует игнорировать этот сигнал и обрабатывать ошибку записи. Как временная мера помогает
IgnoreSIGPIPE=yes, если параметр был отключён.
- Почему происходит
- При
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 (Ubuntu 24.04)
Воспроизведено на unit с конвейером в ExecStart через sh -c.