SSH:防止stdout反对断开连接

时间:2011-06-24 16:32:48

标签: linux unix ssh

我的服务器部署脚本通过SSH触发长时间运行的进程,如下所示:

ssh host 'install.sh'

由于家中的互联网连接不是最好的,我有时会在install.sh运行时断开连接。 (这很容易通过关闭终端窗口来模拟。)我真的希望install.sh脚本在这些情况下继续运行,这样我就不会遇到中断的apt-get进程和类似的麻烦

install.sh被杀的原因似乎是当SSH会话被拉扯时stdout和stderr被关闭,因此写入它们失败了。 (顺便说一下,这不是SIGHUP的问题 - 使用nohup没有任何区别。)如果我将touch ~/1 && echo this fails && touch ~/2放入install.sh,则只有~/1是创建

因此运行ssh host 'install.sh &> install.out'解决了问题,但随后我失去了任何“实时”进度和错误输出。

所以我的问题是:通过SSH运行进程是一种简单/惯用的方法,这样如果SSH死掉它就不会崩溃,但是在运行时我仍能看到输出?


我尝试过的解决方案:

  • 当我手动运行时,我会使用screen这样的情况,但我不认为这会有很大帮助,因为我需要自动运行install.sh shell脚本。屏幕似乎是为了交互式使用(它抱怨“必须连接到终端。”)。

  • 使用install.sh 2>&1 | tee install.out也无济于事(我认为这可能是愚蠢的)。

  • 您可以将stdout / stderr重定向到install.out,然后再tail -f。以下代码段实际上有效:

    touch install.out &&  # so tail does not bark (race condition)
    (install.sh < /dev/null &> install.out &
    tail --pid "$!" -F install.out)
    

    但肯定有一种不太尴尬的方法可以做同样的事情吗?

2 个答案:

答案 0 :(得分:3)

尝试使用屏幕:

screen ./install.sh    

如果你的ssh会话被中断,你可以通过另一个ssh连接简单地重新连接到会话:

screen -x

您可以使用-t开关为您的ssh会话提供终端:

ssh -t server screen ./install.sh

答案 1 :(得分:0)

install.sh 2&gt;&amp; 1 | tee install.out

如果唯一的问题没有得到stderr。你没有确切地说为什么发球台是不可接受的。您可能需要其他nohup / stdin调整。