124

我正在使用一个初始化脚本来运行一个简单的进程,该进程以:

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

名为 $DAEMON 的进程通常将日志信息打印到其标准输出。据我所知,这些数据没有存储在任何地方。

我想将 $DAEMON 的标准输出写入或附加到某个文件中。

我知道的唯一解决方案是告诉 start-stop-daemon 直接调用 shellscript 而不是 $DAEMON;然后脚本调用 $DAEMON 并写入日志文件。但这需要一个额外的脚本,就像修改守护程序本身一样,似乎是解决这种常见任务的错误方法。

4

11 回答 11

134

要扩展 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 进程并忽略运行该守护进程的实际子进程。

于 2014-01-09T20:00:09.113 回答
47

你需要做:

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"

此外,如果您使用--chuidor --user,请确保用户可以写入/var/log或现有的/var/log/some.log. 最好的方法是让该用户拥有一个/var/log/subdir/

于 2012-09-30T16:29:38.610 回答
41

看来您现在应该可以在开始捕获守护程序输出--no-close时使用该参数了。从 Debian 1.16.5 版本开始,该软件包中提供了start-stop-daemon新功能:dpkg

添加新的 --no-close 选项以禁用在 --background 上关闭 fds。

这使调用者能够查看用于调试目的的进程消息,或者能够将文件描述符重定向到日志文件、syslog 或类似文件。

于 2012-12-21T14:26:51.947 回答
14

使用 openrc(例如,它是 gentoo 或 alpine linux 上的默认设置)start-stop-daemon具有-1-2选项:

-1, --stdout 将标准输出重定向到文件

-2, --stderr 将标准错误重定向到文件

所以你可以写:

start-stop-daemon --start --quiet --chuid $DAEMONUSER    \
    --make-pidfile --pidfile $PIDFILE --background       \
    --exec $DAEMON $DAEMON_ARGS -1 $LOGFILE -2 $LOGFILE
于 2016-04-21T14:47:19.100 回答
10

捕获守护进程的输出并将其保存到文件中并不难:

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

但是,此解决方案可能对logrotate.

将输出捕获到 syslog 可能会更好。在Debian上,这将匹配 systemd 服务的行为。以下直接尝试重写上述示例是错误的,因为它在停止守护进程后留下了两个无父(“僵尸”)进程(记录器和守护进程),因为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"""

为了使它工作,我们需要一个包装器,它在收到SIGTERMfrom时终止其子级start-stop-daemon。有一些:

杜安德
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 个进程(主管daemonsu守护进程本身)。
缺点$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 个进程(主管pipexeclogger守护进程本身);如果守护程序立即终止(例如无效命令) ,则status_of_proc -p $PIDFILE "$DAEMON" "$NAME"正确报告失败。
缺点:没有。

这是赢家——似乎运行良好的最简单、简洁的解决方案。

于 2015-11-09T09:55:56.570 回答
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
于 2015-11-12T09:18:01.613 回答
4

引用一个旧的邮件列表:

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 ?

于 2012-06-10T00:39:07.140 回答
3

我不确定 "$DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1" 是否会关闭日志文件的文件描述符......这意味着如果你的守护进程永远运行,我不确定该 logrotate 或其他清理磁盘空间的机制将起作用。由于它是 > 而不是 >>,因此建议的命令还会在重新启动时截断现有日志。如果您想查看守护程序崩溃的原因,并且它会自动重新启动,那可能不是很有帮助。

另一个选项可能是“$DAEMON | logger”。logger 是一个将记录到 syslog (/var/log/messages) 的命令。如果您也需要 stderr,我认为您可以使用 "$DAEMON 1>&2 | logger"

于 2013-01-21T20:45:41.073 回答
2

假设它是 bash (尽管其他一些 shell 也可能允许这样做),该行:

exec >>/tmp/myDaemon.log

会将所有未来的标准输出发送到该文件。那是因为exec没有程序名只会做一些重定向魔术。从bash手册页:

如果未指定 command,则任何重定向都在当前 shell 中生效。

所述文件的管理当然是另一个问题。

于 2011-11-24T04:03:35.560 回答
2

有一个选项--no-closestart-stop-daemon意思是“在后台运行时不要关闭任何 fd”。

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

这会将进程的 stdout/stderr 重定向start-stop-daemon到文件。并且您的可执行文件从其父进程继承 stdout/stderr start-stop-daemon

于 2020-09-02T05:12:07.277 回答
1

怎么样:

sudo -u myuser -i start-stop-daemon ...
于 2012-11-22T13:42:20.813 回答