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

时间:2010-11-06 12:58:23

标签: bash ssh nohup mutt

我想通过ssh远程启动脚本:

ssh user@remote.org -t 'cd my/dir && ./myscript data my@email.com'

脚本执行各种正常工作,直到使用nohup:

nohup time ./myprog $1 >my.log && mutt -a ${1%.*}/`basename $1` -a ${1%.*}/`basename ${1%.*}`.plt $2 < my.log 2>&1 &

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

  

与remote.org的连接已关闭。

这里有什么问题?

感谢您的帮助

3 个答案:

答案 0 :(得分:6)

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

您的time ./myprog进程受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 " &

所以整个管道都受到保护。 (如果这不能解决问题,可能需要对文件描述符做一些事情 - 例如,mutt可能有其他问题,终端没有 - 或者引用可能需要根据参数进行调整 - 但是试试看现在...)

答案 1 :(得分:5)

This answer可能会有所帮助。总之,要达到预期效果,您必须执行以下操作:

  1. 重定向远程nohup'ed命令的所有I / O
  2. 告诉您的本地SSH命令在启动远程进程后立即退出。
  3. 引用the answer I already mentioned,然后引用wikipedia

      

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

    nohup myprogram > foo.out 2> foo.err < /dev/null &
    

    更新

    我刚刚成功使用这种模式:

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

答案 2 :(得分:0)

设法解决此问题,在这种情况下,我需要使用与此处其他答案类似的技术通过ssh远程启动后台脚本,但从某种意义上讲,我觉得它更简单,更简洁(至少,它使我的代码更短)并且-我相信-看起来更好),通过使用流关闭重定向语法明确关闭所有三个流(如以下位置所述:

  1. https://unix.stackexchange.com/questions/131801/closing-a-file-descriptor-vs

  2. https://unix.stackexchange.com/questions/70963/difference-between-2-2-dev-null-dev-null-and-dev-null-21

  3. http://www.tldp.org/LDP/abs/html/io-redirection.html#CFD

  4. https://www.gnu.org/software/bash/manual/html_node/Redirections.html

不是更广泛使用但(IMHO)的黑客“重定向到/ dev / null /从/ dev / null重定向”,从而导致看似简单:

    nohup script.sh >&- 2>&- <&-&

2>&1的效果与2>&-一样好,但是我觉得后者的含义要稍微清晰一些。 ;)大多数人可能在最终的“背景工作”与符号之前有一个空格,但是由于它不是必需的(因为在常规用法中,“与”符号本身的功能就像分号一样),因此我倾向于忽略它。 :)