joe*_*dle 115 logging stdout init.d start-stop-daemon
我使用init脚本来运行一个简单的进程,该进程以:
start-stop-daemon --start --quiet --chuid $DAEMONUSER \
--make-pidfile --pidfile $PIDFILE --background \
--exec $DAEMON $DAEMON_ARGS
Run Code Online (Sandbox Code Playgroud)
名为$ DAEMON的进程通常将日志信息打印到其标准输出.据我所知,这些数据没有存储在任何地方.
我想将$ DAEMON的stdout写入或附加到某个文件中.
我知道的唯一解决方案是告诉start-stop-daemon直接调用一个shellscript而不是$ DAEMON; 然后脚本调用$ DAEMON并写入日志文件.但这需要一个额外的脚本,就像修改守护进程本身一样,似乎是解决这种常见任务的错误方法.
小智 122
要扩展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"
Run Code Online (Sandbox Code Playgroud)
使用exec运行守护程序允许stop正确停止子进程而不仅仅是bash parent.
使用--startas而不是--exec确保其pid正确检测进程,并且如果多次调用start,则不会错误地启动守护进程的多个实例.否则,start-stop-daemon将查找/ bin/bash进程并忽略运行该守护进程的实际子进程.
you*_*ayy 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"
Run Code Online (Sandbox Code Playgroud)
此外,如果您使用--chuid或--user,请确保用户可以写入/var/log或现有/var/log/some.log.最好的方法是让该用户拥有一个/var/log/subdir/.
Sté*_*ane 40
--no-close在开始start-stop-daemon捕获守护程序输出时,您似乎应该能够立即使用该参数.从Debian版本1.16.5开始,这个新功能在dpkg包中提供:
添加新的--no-close选项以禁用--background上的关闭fds.
这使调用者能够查看进程消息以进行调试,或者能够将文件描述符重定向到日志文件,syslog或类似文件.
lit*_*ude 11
随着OpenRC的(这是在Gentoo或例如高山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
Run Code Online (Sandbox Code Playgroud)
捕获守护进程的输出并将其保存到文件并不太难:
start-stop-daemon --start --background \
--pidfile $PIDFILE --make-pidfile \
--chuid $DAEMON_USER \
--startas $DAEMON --no-close \
-- $DAEMON_ARGS >> $LOGFILE 2>&1
Run Code Online (Sandbox Code Playgroud)
然而,这种解决方案可能不是最理想的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"""
Run Code Online (Sandbox Code Playgroud)
要使它工作我们需要在收到终止其子女的包装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"""
Run Code Online (Sandbox Code Playgroud)
注意: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"""
Run Code Online (Sandbox Code Playgroud)
优点: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}'
Run Code Online (Sandbox Code Playgroud)
优点:3个处理(主管pipexec,logger和守护程序本身); 如果守护程序立即终止(例如无效命令),则status_of_proc -p $PIDFILE "$DAEMON" "$NAME"正确报告失败.
缺点:没有.
这是赢家 - 最简单,最简洁的解决方案似乎运作良好.
小智 6
通常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
Run Code Online (Sandbox Code Playgroud)