使用SSH进行远程同步然后asynchronous执行

TL; DR

我想远程执行一个同步开始的脚本(如果准备命令失败,本地ssh命令就会失败),然后进行asynchronous,从而终止本地的ssh命令。

细节

我在远程服务器上有一个脚本,可以慢慢下载一个多GB的文件。 我想通过SSH从本地服务器启动这个脚本,使用ssh remote-server'nohup / path / to / script arguments',但是当我知道脚本已经成功开始下载时,终止SSH连接。 一旦启动,SSH连接就没有任何用处,在下载过程中系统失败,并阻止本地服务器的执行。

我不能只执行ssh -fssh &因为如果远程脚本没有启动,在下载之前第一个命令失败,或者如果远程服务器不可用,我需要命令在本地服务器上失败。

我已经尝试过各种nohupscreen技巧。 我得到的最接近的是:

  • 由本地服务器启动:

     ssh -t me@remote-server 'screen -S long-download /path/to/download.sh' 

    要么

     ssh -t me@remote-server 'nohup screen -S long-download /path/to/download.sh' 
  • 在远程服务器上启动的download.sh

     preliminary-instructions # if anything fails so far then the local server's ssh command should fail synchronously download-command & some-more-checking screen -d long-download # we can now safely end the ssh session 

但不知何故screen仍然死亡…

示例复制代码

  • 在远程服务器上,在/path/to/test.sh

     #!/bin/bash # uncomment this line to validate synchronous failure sleep 10 && echo foo >/tmp/bar & screen -d long-download 
  • 本地:

     ssh -t me@remote-server 'nohup screen -S long-download /path/to/test.sh' 

看看ssh子系统。 我做了类似的事情,但没有一个脚本(即我使用a.out /精灵编译的程序。)但我刚刚testing了一个bash脚本,它的工作原理。

从ssh手册页:

  -s May be used to request invocation of a subsystem on the remote system. Subsystems are a feature of the SSH2 protocol which facilitate the use of SSH as a secure transport for other appli- cations (eg. sftp(1)). The subsystem is specified as the remote command. 

在客户端上使用-s(小写)指定子系统

将另一个Subsystem条目添加到指向您的脚本的服务器上的sshd_config。

  # override default of no subsystems Subsystem logger /usr/local/libexec/my-logger.sh Subsystem sftp /usr/libexec/sftp-server 

您的脚本应像任何其他具有执行权限的文件一样启动。 我的例子:

 #! /usr/local/bin/bash logger "testing 1.2.3" echo "return text from my-logger" exec 0>&- # close stdin exec 0<&- exec 1>&- # close stdout exec 1<&- exec 2>&- # close stderr exec 2<&- logger "subsystem: nohup new script" nohup /path/to/another/script/logger2.sh & logger "subsystem: the subsystem started script is now done" exit 0 

您应该能够返回有用的错误文本成功或失败。 ssh连接(以及stdin,stdout和stderr)直到子系统结束。 子系统可以继续运行或不运行。

让你的其他脚本(上面的logger2.sh)睡5-10分钟,这样你就可以使用netstat来查看ssh连接了,ssh客户端返回到shell,例如ps ax显示脚本仍在后台运行。 这个脚本可能还需要closuresfd等。这只是一个简单的例子。 祝你好运。

BostonDriver答案的替代解决schemescreen -d -m

async-launcher.sh

 #!/bin/bash echo connected && # preliminary-command && screen -S index-fetch -d -m $(cd ${0%/*} && pwd -P)/long-download.sh sleep 5 # ensure long-download.sh didn't immediately fail if ((`screen -ls | grep index-fetch | wc -l`)); then echo ok else echo ko exit 1 fi 

long-download.sh可以包含所有的asynchronous命令。

用一个简单的ssh me@remote-server /path/to/async-launcher.sh 。 还有一个额外的好处:屏幕可以在以后重新附加。