bash 如何从 Debian 上的 start-stop-daemon 启动的进程重定向进程输出?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12787768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I redirect process output from a process started with start-stop-daemon on Debian?
提问by Pryo
There are several questions about this already but none of them seem to work. I have a production system that is currently down and I need to be able to get the stderr output from the daemon quickly to debug it.
已经有几个关于此的问题,但它们似乎都不起作用。我有一个当前已关闭的生产系统,我需要能够快速从守护程序获取 stderr 输出以对其进行调试。
I thought I could just redirect the output from the point it is called (in an init.d script) but it is proving extremely difficult.
我以为我可以从它被调用的点(在 init.d 脚本中)重定向输出,但事实证明它非常困难。
start-stop-daemon -d $DDIR -b -m --start --quiet -pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS > /var/log/daemon.log 2>&1 \
|| return 2
This does not work. I tried running a shell script that calls the executable and redirects the output but still the log file remained empty (and I do know that the process is outputting information).
这不起作用。我尝试运行一个调用可执行文件并重定向输出的 shell 脚本,但日志文件仍然是空的(我知道进程正在输出信息)。
Any help would be extremely appreciated.
任何帮助将不胜感激。
回答by Tim S.
If you have start-stop-daemon >= version 1.16.5 you simply call it with --no-closeto be able to redirect the output of the startedprocess.
如果您有 start-stop-daemon >= 1.16.5 版,您只需调用它就--no-close可以重定向已启动进程的输出。
From man start-stop-daemon:
来自man start-stop-daemon:
-C, --no-close
Do not close any file descriptor when forcing the daemon into the background (since version 1.16.5). Used for debugging purposes to see the process output, or to redirect file descriptors to log the process output. Only relevant when using --background.
-C, --no-close
Do not close any file descriptor when forcing the daemon into the background (since version 1.16.5). Used for debugging purposes to see the process output, or to redirect file descriptors to log the process output. Only relevant when using --background.
回答by Rafael
As far as i remember, this is impossible, usually when i need to get data from a daemon process i either log it before hand or create a monitor program that connects to the program via network sockets or named pipes or any other interprocess communication mechanism.
据我所知,这是不可能的,通常当我需要从守护进程获取数据时,我要么事先记录它,要么创建一个监视器程序,该程序通过网络套接字或命名管道或任何其他进程间通信机制连接到该程序。
回答by Rafa? Rawicki
Calling start-stop-daemonwith > /var/log/daemon.log 2>&1will redirect start-stop-daemon's output and not the started daemon's output. Start-stop-daemonwill close standard output/input descriptors before running a daemon.
调用start-stop-daemonwith> /var/log/daemon.log 2>&1将重定向start-stop-daemon的输出而不是启动的守护程序的输出。启动停止守护程序将在运行守护程序之前关闭标准输出/输入描述符。
Wrapping an executable in a simple shell script like that:
将可执行文件包装在一个简单的 shell 脚本中,如下所示:
#!/bin/bash
STDERR=
shift
DAEMON=
shift
$DAEMON 2>$STDERR $*
works for me - maybe you should check file permissions?
对我有用 - 也许你应该检查文件权限?
There is a problem with this naive solution - when start-stop-daemonkills this wrapper, the wrapped daemon will be left alive. That cannot be easily solved in bash, because you cannot run signal handlers during the script execution (see trapdocumentation for details). You have to write a C wrapper which looks like that:
这种幼稚的解决方案有一个问题——当start-stop-daemon杀死这个包装器时,被包装的守护进程将保持活动状态。这在 bash 中无法轻松解决,因为您无法在脚本执行期间运行信号处理程序(trap有关详细信息,请参阅文档)。您必须编写一个 C 包装器,如下所示:
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char** argv){
int fd_err;
fd_err = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC);
dup2(fd_err, STDERR_FILENO);
close(fd_err);
return execvp(argv[2], argv + 2);
}
(I've omitted error checking for clarity).
(为清楚起见,我省略了错误检查)。
回答by lauhub
Here is a solution that may work (based on the solution given here).
这是一个可行的解决方案(基于此处给出的解决方案)。
At the beginning of your init.d script (and after the header), add the following:
在 init.d 脚本的开头(以及标题之后),添加以下内容:
exec > >(tee --append /var/log/daemon.log)
#You may also choose to log to /var/log/messages using this:
#exec > >(logger -t MY_DAEMON_NAME)
#And redirect errors to the same file with this:
exec 2>&1
This will log all that is invoked during your script, including start-stop-daemonoutput.
这将记录在您的脚本期间调用的所有内容,包括start-stop-daemon输出。

