通过 ssh 启动包含 nohup 的远程脚本
我想通过 ssh 远程启动一个脚本,如下所示:
ssh [email protected] -t 'cd my/dir && ./myscript data [email protected]'
该脚本会执行各种工作正常的事情,直到它与 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的连接已关闭。
这里有什么问题呢?
感谢您的帮助
I want to start a script remotely via ssh like this:
ssh [email protected] -t 'cd my/dir && ./myscript data [email protected]'
The script does various things which work fine until it comes to a line with nohup:
nohup time ./myprog $1 >my.log && mutt -a ${1%.*}/`basename $1` -a ${1%.*}/`basename ${1%.*}`.plt $2 < my.log 2>&1 &
it is supposed to do start the program myprog, pipe its output to mylog and send an email with some datafiles created by myprog as attachment and the log as body. Though when the script reaches this line, ssh outputs:
Connection to remote.org closed.
What is the problem here?
Thanks for any help
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的命令在后台运行进程管道,因此调用脚本将立即退出(或很快退出)。这将导致 ssh 关闭连接。这反过来会导致
SIGHUP
被发送到附加到-t
选项导致创建的终端的任何进程。您的
time ./myprog
进程受nohup
保护,因此它应该继续运行。但你的mutt
不是,这可能就是这里的问题。我建议您将命令行更改为:以便整个管道受到保护。 (如果这不能解决问题,则可能需要对文件描述符进行一些处理 - 例如 mutt 可能会因终端不在周围而出现其他问题 - 或者引用可能需要根据参数进行调整 - 但请尝试一下现在...)
Your command runs a pipeline of processes in the background, so the calling script will exit straight away (or very soon afterwards). This will cause ssh to close the connection. That in turn will cause a
SIGHUP
to be sent to any process attached to the terminal that the-t
option caused to be created.Your
time ./myprog
process is protected by anohup
, so it should carry on running. But yourmutt
isn't, and that is likely to be the issue here. I suggest you change your command line to:so the entire pipeline gets protected. (If that doesn't fix it it may be necessary to do something with file descriptors - for instance mutt may have other issues with the terminal not being around - or the quoting may need tweaking depending on the parameters - but give that a try for now...)
这个答案可能是有帮助。总之,要达到预期的效果,您必须执行以下操作:
引用我已经提到的答案,依次引用 wikipedia:
更新
我刚刚成功使用了这种模式:
This answer may be helpful. In summary, to achieve the desired effect, you have to do the following things:
Quoting the answer I already mentioned, in turn quoting wikipedia:
UPDATE
I've just had success with this pattern:
设法解决这个用例,我需要使用类似于此处其他答案的技术通过 ssh 远程启动后台脚本,但在某种程度上我觉得更简单和干净(至少,它使我的代码更短,并且 -我相信 - 更好看),通过使用流关闭重定向语法显式关闭所有三个流(如以下位置所述:
https://unix.stackexchange.com/questions/131801/ending-a-file-descriptor-vs
https: //unix.stackexchange.com/questions/70963/difference- Between-2-2-dev-null-dev-null-and-dev-null-21
http://www.tldp.org/LDP/abs/html/io-redirection.html#CFD
https: //www.gnu.org/software/bash/manual/html_node/Redirections.html
而不是更广泛使用但(恕我直言)更黑客的“重定向到/from /dev/null”,结果看似简单:
2>&1
与 2>&- 一样有效,但我觉得后者更加清晰。 ;) 大多数人可能在最后的“后台作业”& 符号之前有一个空格,但由于它不是必需的(因为 & 符号本身在正常使用中的功能类似于分号),所以我更愿意省略它。 :)Managed to solve this for a use case where I need to start backgrounded scripts remotely via ssh using a technique similar to other answers here, but in a way I feel is more simple and clean (at least, it makes my code shorter and -- I believe -- better-looking), by explicitly closing all three streams using the stream-close redirection syntax (as discussed at the following locations:
https://unix.stackexchange.com/questions/131801/closing-a-file-descriptor-vs
https://unix.stackexchange.com/questions/70963/difference-between-2-2-dev-null-dev-null-and-dev-null-21
http://www.tldp.org/LDP/abs/html/io-redirection.html#CFD
https://www.gnu.org/software/bash/manual/html_node/Redirections.html
Rather than the more widely used but (IMHO) hackier "redirect to/from /dev/null", resulting in the deceptively simple:
2>&1
works just as well as 2>&-, but I feel the latter is ever-so-slightly more clear. ;) Most people might have a space preceding the final "background job" ampersand, but since it is not required (as the ampersand itself functions like a semicolon in normal usage), I prefer to omit it. :)