当没有分配 TTY 时,如何强制输出到文件?

当没有分配 TTY 时,如何强制输出到文件?

我有一个初始化脚本,它在 start() 函数中执行如下操作:

runuser -s /bin/bash - prog -c "nohup php /foo/bar.php 2>&1 >> /var/log/bar.log &"

当我通过 SSH 进入机器并调用初始化脚本时:

server:~$ sudo /etc/init.d/foo restart

一切正常 — 所有输出均符合bar.log预期并且我可以注销。

但是,如果我直接从 SSH 命令调用初始化脚本:

workstation:~$ ssh server sudo /etc/init.d/foo restart

然后输出将到达我的本地终端,而不是日志,并且我无法关闭 SSH 连接,否则会丢失所有输出(这些输出不再进入日志文件)。当然,有更好的方法来制定 init 脚本,任何建议都会受到赞赏,但是这个例子中的重定向发生了什么?

答案1

尝试这个:

runuser -s /bin/bash - prog -c "nohup php /foo/bar.php >> /var/log/bar.log 2>&1 &"

当你进行重定向时这确实很重要。

在您的示例中,您将 stderr 重定向到 stdout,然后将 stdout 重定向到 /var/log/bar.log。但这并不意味着 stderr 也重定向到 /var/log/bar.log

shell 从左到右解释你的命令,所以如果你想将两个流重定向到文件,你首先需要将 stdout 重定向到 /var/log/bar.log,然后将 stderr 重定向到 stdout 的位置,即 /var/log/bar.log。

很难用外语解释。抱歉 :)

答案2

我一直在努力寻找这个答案......

使用 SSH 远程启动进程部分回答了这组问题。

由于 ssh 将 stdin/stdout/stderr 连接到本地终端,因此通过 ssh 调用行启动时,重定向实际上并不会生效。

而且由于控制 tty 归 ssh 所有,如果它消失,那么 tty 和通过 ssh 调用行启动的任何程序也都消失了。在这种情况下,/etc/init.d/foo 可能不是通过 /etc/init.d/functions daemon() 启动的,实际程序也不会调用 daemon() C 函数,这两种情况下,程序都会从​​控制 tty 中分离出来,从而允许 ssh 干净地退出,而不会终止目标程序。并且在此过程中允许重定向接管。

我知道这不是一个好的解释。希望其他人能够理解上述内容并给出明确的答案。

相关内容