我使用init脚本来运行一个简单的过程,该过程以:
开头start-stop-daemon --start --quiet --chuid $DAEMONUSER \
--make-pidfile --pidfile $PIDFILE --background \
--exec $DAEMON $DAEMON_ARGS
名为$ DAEMON的进程通常会将日志信息打印到其标准输出。据我所知,这些数据没有存储在任何地方。
我想将$ DAEMON的stdout写入或附加到某个文件中。
我知道的唯一解决方案是告诉start-stop-daemon直接调用一个shellscript而不是$ DAEMON;然后脚本调用$ DAEMON并写入日志文件。但这需要一个额外的脚本,就像修改守护进程本身一样,似乎是解决这种常见任务的错误方法。
答案 0 :(得分:117)
要扩展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 parent。
使用--startas
代替--exec
可确保其pid正确检测进程,并且如果多次调用start,则不会错误地启动守护程序的多个实例。否则,start-stop-daemon将查找/ bin / bash进程并忽略运行守护进程的实际子进程。
答案 1 :(得分:45)
你需要这样做:
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/
。
答案 2 :(得分:40)
在启动--no-close
以捕获守护程序输出时,您现在应该能够使用start-stop-daemon
参数。从版本1.16.5开始,dpkg
包中的new feature可用于Debian:
添加新的--no-close选项以禁用--background上的关闭fds。
这使调用者能够查看用于调试的进程消息 目的,或者能够将文件描述符重定向到日志文件, 系统日志或类似的。
答案 3 :(得分:11)
使用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
答案 4 :(得分:8)
捕获守护程序的输出并将其保存到文件中并不太难:
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服务的行为。
以下直接尝试重写上面的示例是错误,因为它在停止守护进程后留下了两个无父(“僵尸”)进程(logger和守护进程),因为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
后终止其子级。有一些:
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个进程(主管daemon
,su
和守护进程本身)。
缺点:由于混淆守护程序的命令行选项而难以管理$PIDFILE
;
如果守护程序立即终止(例如无效命令)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"
正确报告失败
缺点:无。
这是赢家 - 最简单,最简洁的解决方案似乎运作良好。
答案 5 :(得分:5)
通常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
答案 6 :(得分: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首先在哪里?
答案 7 :(得分:3)
我不确定“$ DAEMON $ DAEMON_ARGS> /var/log/some.log 2>& 1”是否会关闭日志文件的文件描述符...这意味着如果你的守护进程永远运行,我不确定logrotate或其他清理磁盘空间的机制是否有效。因为它是>而不是>>,建议的命令也会在重启时截断现有日志。如果你想知道守护进程崩溃的原因,并且它会自动重启,那可能不是很有帮助。
另一种选择可能是“$ DAEMON | logger”。 logger是一个将记录到syslog(/ var / log / messages)的命令。如果你也需要stderr,我想你可以使用“$ DAEMON 1>& 2 | logger”
答案 8 :(得分:2)
假设它是bash(尽管其他一些shell也允许这样做),行:
exec >>/tmp/myDaemon.log
将所有未来的标准输出发送到该文件。这是因为没有程序名称的exec
只会做一些重定向魔术。从bash
手册页:
如果未指定command,则任何重定向都会在当前shell中生效。
管理上述文件当然是另一个问题。
答案 9 :(得分:2)
--no-close
有一个选项start-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
这会将进程start-stop-daemon
的标准输出/标准错误重定向到文件。并且您的可执行文件会从其父进程start-stop-daemon
继承stdout / stderr。
答案 10 :(得分:1)
怎么样:
sudo -u myuser -i start-stop-daemon ...