通过包含nohup的ssh启动远程脚本

lit*_*tro 7 ssh bash nohup mutt

我想通过ssh远程启动脚本,如下所示:

ssh user@remote.org -t 'cd my/dir && ./myscript data my@email.com'
Run Code Online (Sandbox Code Playgroud)

该脚本执行各种工作正常,直到与nohup行:

nohup time ./myprog $1 >my.log && mutt -a ${1%.*}/`basename $1` -a ${1%.*}/`basename ${1%.*}`.plt $2 < my.log 2>&1 &
Run Code Online (Sandbox Code Playgroud)

它应该启动程序myprog,将其输出传递给mylog并发送一封电子邮件,其中包含myprog创建的一些数据文件作为附件,日志作为正文.虽然当脚本到达此行时,ssh输出:

与remote.org的连接已关闭.

这里有什么问题?

谢谢你的帮助

psm*_*ars 6

您的命令在后台运行一系列进程,因此调用脚本将立即退出(或很快就会退出).这将导致ssh关闭连接.这反过来将导致a SIGHUP被发送到附加到终端的任何进程,该进程-t导致创建.

您的time ./myprog进程受a保护nohup,因此应继续运行.但你mutt不是,这可能是这里的问题.我建议你将命令行改为:

nohup sh -c "time ./myprog $1 >my.log && mutt -a ${1%.*}/`basename $1` -a ${1%.*}/`basename ${1%.*}`.plt $2 < my.log 2>&1 " &
Run Code Online (Sandbox Code Playgroud)

所以整个管道都受到保护.(如果这不能解决问题,则可能需要对文件描述符执行某些操作 - 例如,mutt可能有其他问题,终端没有 - 或者引用可能需要调整,具体取决于参数 - 但是尝试一下现在...)


小智 5

这个答案可能会有所帮助.总之,要达到预期的效果,您必须执行以下操作:

  1. 重定向远程nohup'ed命令上的所有I/O.
  2. 告诉您的本地SSH命令在启动远程进程后立即退出.

引用我已经提到的答案,反过来引用维基百科:

例如,当通过SSH登录时,Nohuping后台作业很有用,因为后台作业可能会因为竞争条件导致shell挂起[2].通过重定向所有三个I/O流也可以克服此问题:

nohup myprogram > foo.out 2> foo.err < /dev/null &
Run Code Online (Sandbox Code Playgroud)

UPDATE

我刚刚用这种模式取得了成功:

ssh -f user@host 'sh -c "( (nohup command-to-nohup 2>&1 >output.file </dev/null) & )"'
Run Code Online (Sandbox Code Playgroud)