Как я могу записать стандартный вывод процесса, запущенного start-stop-daemon? - PullRequest
112 голосов
/ 24 ноября 2011

Я использую сценарий инициализации для запуска простого процесса, который начинается с:

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec $DAEMON $DAEMON_ARGS

Процесс с именем $ DAEMON обычно выводит информацию журнала в свой стандартный вывод.Насколько я могу судить, эти данные нигде не хранятся.

Я хотел бы написать или добавить стандартный вывод $ DAEMON в файл где-либо.скажите start-stop-daemon, чтобы он вызывал шеллскрипт вместо $ DAEMON напрямую;Затем скрипт вызывает $ DAEMON и записывает в файл журнала.Но для этого требуется дополнительный скрипт, который, как и модификация самого демона, кажется неправильным способом решения такой распространенной задачи.

Ответы [ 10 ]

118 голосов
/ 10 января 2014

Расширить ответ ypocat, поскольку он не позволяет мне комментировать:

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
 --make-pidfile --pidfile $PIDFILE --background       \
 --startas /bin/bash -- -c "exec $DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1"

Использование exec для запуска демона позволяет stop правильно останавливать дочерний процесс, а не только родительский bash.

Использование --startas вместо --exec гарантирует, что процесс будет правильно определен pid и не будет ошибочно запускать несколько экземпляров демона, если start вызывается несколько раз. В противном случае start-stop-daemon будет искать процесс / bin / bash и игнорировать фактический дочерний процесс, выполняющий демон.

45 голосов
/ 30 сентября 2012

Вам нужно сделать:

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec /bin/bash -- -c "$DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1"

Также, если вы используете --chuid или --user, убедитесь, что пользователь может писать в /var/log или в существующий /var/log/some.log.Лучше всего, если у этого пользователя есть /var/log/subdir/.

40 голосов
/ 21 декабря 2012

Похоже, что теперь вы должны использовать параметр --no-close при запуске start-stop-daemon для захвата вывода демона. Эта новая функция доступна в пакете dpkg начиная с версии 1.16.5 в Debian:

Добавить новую опцию --no-close, чтобы отключить закрытие fds на --background.

Это позволило вызывающей стороне видеть сообщения процесса для отладки. цели, или чтобы иметь возможность перенаправить файловые дескрипторы в файлы журнала, системный журнал или аналогичный.

11 голосов
/ 21 апреля 2016

С openrc (который по умолчанию используется в Gentoo или Alpine Linux), например, start-stop-daemon имеет опции -1 и -2:

-1, --stdout Перенаправить стандартный вывод в файл

-2, --stderr Перенаправить stderr в файл

Так что вы можете просто написать:

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec $DAEMON $DAEMON_ARGS -1 $LOGFILE -2 $LOGFILE
8 голосов
/ 09 ноября 2015

Нетрудно собрать выходные данные демона и сохранить их в файл:

start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas $DAEMON --no-close \
  -- $DAEMON_ARGS >> $LOGFILE 2>&1

Однако это решение может быть неоптимальным для logrotate.

Возможно, было бы лучше захватитьвывод в системный журнал.На Debian это будет соответствовать поведению системных сервисов.Следующая прямая попытка переписать приведенный выше пример - неверно , поскольку после остановки демона после двух демонов ("зомби") он оставляет после остановки демона, поскольку start-stop-daemon завершает работу только его потомка, но невсе потомки:

## Do not use this!
start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas /bin/sh \
  -- -c """exec $DAEMON $DAEMON_ARGS | /usr/bin/logger --tag $NAME"""

Чтобы заставить его работать, нам нужна оболочка, которая завершает свои дочерние элементы при получении SIGTERM от start-stop-daemon.Вот некоторые из них:

duende :
start-stop-daemon --start --background \
  --pidfile $PIDFILE \
  --startas /usr/sbin/duende \
  -- --pid $PIDFILE --chroot=/ --uid 65534 --ident $NAME \
  /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec ${DAEMON} $DAEMON_ARGS"""

Примечание: uid=65534 является пользователем nobody.

Плюсы : это работает иэто относительно просто.
Минусы : 4 процесса (супервизор duende, его форк с отброшенными привилегиями (логгер), su и сам демон);обязательный --chroot;Если демон немедленно завершает работу (например, недопустимая команда) status_of_proc -p $PIDFILE "$DAEMON" "$NAME", сообщите о том, что он успешно запущен.

демон :
start-stop-daemon --start --pidfile $PIDFILE \
  --startas /usr/bin/daemon \
  -- --noconfig --name $NAME --stderr=syslog.info --stdout=syslog.info \
  -- /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec $DAEMON $DAEMON_ARGS"""

Плюсы : 3 процесса (супервизор * 1042)*, su и сам демон).
Минусы : Сложно управлять $PIDFILE из-за путаницы в параметрах командной строки daemon ;Если демон немедленно завершает работу (например, неверная команда) status_of_proc -p $PIDFILE "$DAEMON" "$NAME", сообщите о том, что он успешно запущен.

pipexec ( победитель ):

start-stop-daemon --start --background \
  --pidfile $PIDFILE --make-pidfile \
  --chuid $DAEMON_USER \
  --startas /usr/bin/pipexec -- -k \
   -- [ D $DAEMON $DAEMON_ARGS ] [ L /usr/bin/logger --tag $NAME ] '{D:2>D:1}' '{D:1>L:0}'

Плюсы : 3 процесса (супервизор pipexec, logger и сам демон);Если демон немедленно завершает работу (например, неверная команда) status_of_proc -p $PIDFILE "$DAEMON" "$NAME" правильно сообщает о сбое.
Минусы : нет.

Это победитель - самое простое, аккуратное решение, которое, кажется, работает хорошо.

5 голосов
/ 12 ноября 2015

Обычно start-stop-daemon закрывает стандартные файловые дескрипторы при работе в фоновом режиме. Со страницы руководства start-stop-daemon:

-C, --no-close
Не закрывайте файловый дескриптор, когда заставляете демона уходить в фоновый режим. Используется в целях отладки, чтобы увидеть вывод процесса или перенаправление файловых дескрипторов для регистрации выходных данных процесса. Актуально только при использовании --background.

Этот работал для меня:

    start-stop-daemon -b -C -o -c \ 
         $DAEMON_USER -S -x $DAEMON > $DAEMON_LOG 2>&1
4 голосов
/ 10 июня 2012

Цитирование старого списка рассылки:

https://lists.ubuntu.com/archives/ubuntu-uk/2005-June/000037.html

Легко - и если вы хотите использовать start-stop-daemon, возможно, единственный - способ обойти этосоздать небольшой скрипт, содержащий:

#!/bin/sh
exec /home/boinc/boinc/boinc > /home/boinc/log/boinc.log

и затем использовать этот скрипт в качестве аргумента для start-stop-daemon.

Возможно, реальный вопрос, однако, действительно ли это необходимовообще использовать start-stop-daemon?

3 голосов
/ 22 января 2013

Я не уверен, что "$ DAEMON $ DAEMON_ARGS> /var/log/some.log 2> & 1" когда-нибудь закроет дескриптор файла для файла журнала ... что означает, что если ваш демон работает вечно, я ' Я не уверен, что logrotate или другие механизмы для очистки дискового пространства будут работать. Поскольку это> вместо >>, предложенная команда также будет обрезать существующие журналы при перезапуске. Если вы хотите понять, почему произошел сбой демона, и он перезапускается автоматически, это может быть не очень полезно.

Другой вариант может быть "$ DAEMON | logger". logger - это команда, которая регистрирует в системном журнале (/ var / log / messages). Если вам нужен также stderr, я думаю, вы можете использовать «$ DAEMON 1> & 2 | logger»

2 голосов
/ 24 ноября 2011

Предполагая, что это bash (хотя некоторые другие оболочки также могут это разрешить), строка:

exec >>/tmp/myDaemon.log

отправит весь будущий стандартный вывод в этот файл.Это потому, что exec без имени программы просто делает магию перенаправления.Со страницы руководства bash:

Если команда не указана, любые перенаправления вступают в силу в текущей оболочке.

Управление этим файлом является другой проблемой, конечно.

1 голос
/ 22 ноября 2012

Как насчет:

sudo -u myuser -i start-stop-daemon ...
...