使用 SSH 远程启动进程

使用 SSH 远程启动进程

我编写了一个脚本,用于将新服务推送并部署到我控制下的几台机器上,并且为了执行该过程,我使用 ssh 远程启动该过程。

不幸的是,每当我使用 SSH 启动该过程时,SSH 命令似乎都不会返回,从而导致脚本停滞。

该命令指定为:

ssh $user@$host "/root/command &"

每当我运行简单命令(例如 ps 或 who)时,SSH 命令都会立即返回,但是当我尝试启动我的进程时它不会返回。

我尝试过一些技巧,比如将我的进程包装在一个简单的 bash 脚本中,该脚本启动该进程然后退出,但是这也会挂起 SSH 命令(即使 bash 脚本回显成功消息并正常退出)。

是否有人知道导致这种行为的原因是什么,以及如何让 SSH 命令在进程启动后立即返回?

答案1

SSH 将远程 shell 的 stdin、stdout 和 stderr 连接到您的本地终端,以便您可以与远程端运行的命令进行交互。

作为副作用,它将一直运行,直到这些连接被关闭,这只有当远程命令及其所有子命令(!)终止时才会发生(因为子命令(以“&”开头)从其父进程继承 std* 并保持其打开)。

所以你需要使用类似

ssh user@host "/script/to/run < /dev/null > /tmp/mylogfile 2>&1 &"

<、> 和 2>&1 将 stdin/stdout/stderr 从您的终端重定向。然后“&”使您的脚本进入后台。在生产中,您当然会将 stdin/err 重定向到合适的日志文件。

http://osdir.com/ml/network.openssh.general/2006-05/msg00017.html

编辑:

刚刚发现< /dev/null上面的操作是没有必要的(但是重定向 stdout/err)。不知道为什么...

答案2

你可以尝试禁止. 更多细节请参见 man nohup。

ssh host "nohup script &"

如果你想保留远程机器上的输出,这是一个变体

ssh user@host 'export REMOTE=myname; nice nohup ./my-restart >
logfile.log 2>&1 &'

答案3

另一种选择是启动一个分离的screen(1),例如:

ssh -l user host "screen -d -m mycommand"

这将启动一个独立的屏幕(捕获其中的所有交互),然后立即返回,终止 ssh 会话。

只要再聪明才智一点,您就可以通过这种方式解决相当复杂的远程命令调用。

答案4

我认为正确的方法是

ssh user@host exec script.sh &

相关内容