Как я могу зарегистрировать stdout процесса, запущенного start-stop-daemon?
Я использую init script для запуска простого процесса, который начинается с:
start-stop-daemon --start --quiet --chuid $DAEMONUSER \
--make-pidfile --pidfile $PIDFILE --background \
--exec $DAEMON $DAEMON_ARGS
Процесс под названием $DAEMON обычно печатает информацию журнала на его стандартный вывод. Насколько я могу судить, эти данные нигде не хранятся.
Я хотел бы написать или добавить stdout из $DAEMON в файл где-нибудь.
Единственное решение, которое я знаю, - сообщить start-stop-daemon для вызова shellscript вместо $DAEMON напрямую; script затем вызывает $DAEMON и записывает в файл журнала. Но для этого требуется дополнительный script, который, как и изменение самого демона, кажется неправильным способом решения такой общей задачи.
Ответы
Ответ 1
Чтобы расширить ответ на 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
для запуска демона позволяет остановить правильную остановку дочернего процесса, а не только родителя bash.
Использование --startas
вместо --exec
гарантирует, что процесс будет правильно обнаружен его pid и не будет ошибочно запускать несколько экземпляров демона, если start вызывается несколько раз. В противном случае, start-stop-daemon будет искать процесс /bin/ bash и игнорировать фактический дочерний процесс, запускающий демона.
Ответ 2
Вам нужно сделать:
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/
.
Ответ 3
Кажется, вы должны теперь использовать параметр --no-close
при запуске start-stop-daemon
для захвата вывода демона. Эта новая функция доступна в пакете dpkg
с версии 1.16.5 на Debian:
Добавить новую опцию --no-close для отключения закрытия fds на -background.
Это позволило вызывающему абоненту видеть сообщения процесса для отладки целей или иметь возможность перенаправлять файловые дескрипторы на файлы журналов, syslog или аналогичный.
Ответ 4
С openrc (который по умолчанию используется для gentoo или alpine linux) start-stop-daemon
имеет параметры -1
и -2
:
-1, --stdout Перенаправить stdout в файл
-2, --stderr Перенаправить stderr в файл
Итак, вы можете просто написать:
start-stop-daemon --start --quiet --chuid $DAEMONUSER \
--make-pidfile --pidfile $PIDFILE --background \
--exec $DAEMON $DAEMON_ARGS -1 $LOGFILE -2 $LOGFILE
Ответ 5
Не сложно записать вывод демон и сохранить его в файл:
start-stop-daemon --start --background \
--pidfile $PIDFILE --make-pidfile \
--chuid $DAEMON_USER \
--startas $DAEMON --no-close \
-- $DAEMON_ARGS >> $LOGFILE 2>&1
Однако это решение может быть субоптимальным для logrotate
.
Может быть лучше захватить вывод в syslog. На 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
, его вилка с привилегиями сброса (logger), su
и сам демон); обязательный --chroot
;
Если демон немедленно завершает работу (например, неверная команда) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"
сообщит об этом как успешно запущенный.
daemon:
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 процесса (супервизор daemon
, su
и сам демон).
Минусы: трудно управлять $PIDFILE
из-за путаницы параметров командной строки daemon;
Если демон немедленно завершает работу (например, неверная команда) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"
сообщит об этом как успешно запущенный.
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"
правильно сообщает об ошибке.
Минусы: нет.
Это победитель - самое простое, опрятное решение, которое, кажется, хорошо работает.
Ответ 6
Указание старого списка рассылки:
https://lists.ubuntu.com/archives/ubuntu-uk/2005-June/000037.html
Легко - и если вы хотите использовать start-stop-daemon, возможно, единственный способ вокруг него нужно создать небольшой script содержащий:
#!/bin/sh
exec /home/boinc/boinc/boinc > /home/boinc/log/boinc.log
а затем используйте этот script как аргумент для запуска-остановки-демона.
Возможно, реальный вопрос заключается в том, действительно ли необходимо использовать start-stop-daemon в первую очередь?
Ответ 7
Я не уверен, что "$ DAEMON $DAEMON_ARGS > /var/log/some.log 2 > & 1" когда-нибудь закроет дескриптор файла для файла журнала... что означает, что ваш демон запускается вечно, Я не уверен, что логротат или другие механизмы для очистки дискового пространства будут работать. Поскольку он > вместо → , предлагаемая команда также будет обрезать существующие журналы при перезапуске. Если вы хотите узнать, почему демон врезан, и он автоматически перезагружается, это может быть не очень полезно.
Другим вариантом может быть "$ DAEMON | logger". logger - это команда, которая будет регистрироваться в syslog (/var/log/messages). Если вам тоже нужен stderr, я думаю, вы могли бы использовать "$ DAEMON 1 > & 2 | logger"
Ответ 8
Обычно 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
Ответ 9
Предполагая, что это bash (хотя некоторые другие оболочки также могут это допускать), строка:
exec >>/tmp/myDaemon.log
отправит в этот файл весь будущий стандартный вывод. Это потому, что exec
без имени программы просто выполняет некоторую магию перенаправления. На странице bash
man:
Если команда не указана, любые перенаправления вступают в силу в текущей оболочке.
Управление указанным файлом - это еще одна проблема.
Ответ 10
Как насчет:
sudo -u myuser -i start-stop-daemon ...