我有一个初始化脚本,它在 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 干净地退出,而不会终止目标程序。并且在此过程中允许重定向接管。
我知道这不是一个好的解释。希望其他人能够理解上述内容并给出明确的答案。