我想通过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的连接已关闭。
这里有什么问题?
感谢您的帮助
答案 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可能会有所帮助。总之,要达到预期效果,您必须执行以下操作:
引用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远程启动后台脚本,但从某种意义上讲,我觉得它更简单,更简洁(至少,它使我的代码更短)并且-我相信-看起来更好),通过使用流关闭重定向语法明确关闭所有三个流(如以下位置所述:
https://unix.stackexchange.com/questions/131801/closing-a-file-descriptor-vs
https://www.gnu.org/software/bash/manual/html_node/Redirections.html
不是更广泛使用但(IMHO)的黑客“重定向到/ dev / null /从/ dev / null重定向”,从而导致看似简单:
nohup script.sh >&- 2>&- <&-&
2>&1
的效果与2>&-一样好,但是我觉得后者的含义要稍微清晰一些。 ;)大多数人可能在最终的“背景工作”与符号之前有一个空格,但是由于它不是必需的(因为在常规用法中,“与”符号本身的功能就像分号一样),因此我倾向于忽略它。 :)