bash 通过包含 nohup 的 ssh 启动远程脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4113168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
starting remote script via ssh containing nohup
提问by litro
I want to start a script remotely via ssh like this:
我想通过 ssh 远程启动一个脚本,如下所示:
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 一行:
nohup time ./myprog >my.log && mutt -a ${1%.*}/`basename ` -a ${1%.*}/`basename ${1%.*}`.plt < 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:
它应该启动程序 myprog,将其输出通过管道传输到 mylog 并发送一封电子邮件,其中包含由 myprog 创建的一些数据文件作为附件和日志作为正文。虽然当脚本到达这一行时,ssh 输出:
Connection to remote.org closed.
与 remote.org 的连接已关闭。
What is the problem here?
这里有什么问题?
Thanks for any help
谢谢你的帮助
回答by psmears
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 SIGHUPto be sent to any process attached to the terminal that the -toption caused to be created.
您的命令在后台运行进程管道,因此调用脚本将立即退出(或很快退出)。这将导致 ssh 关闭连接。这反过来将导致 aSIGHUP被发送到附加到该-t选项导致创建的终端的任何进程。
Your time ./myprogprocess is protected by a nohup, so it should carry on running. But your muttisn't, and that is likely to be the issue here. I suggest you change your command line to:
您的time ./myprog进程受 保护nohup,因此它应该继续运行。但你mutt不是,这很可能是这里的问题。我建议您将命令行更改为:
nohup sh -c "time ./myprog >my.log && mutt -a ${1%.*}/`basename ` -a ${1%.*}/`basename ${1%.*}`.plt < my.log 2>&1 " &
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...)
所以整个管道都得到了保护。(如果这不能解决它,则可能需要对文件描述符做一些事情 - 例如 mutt 可能有终端不在的其他问题 - 或者引用可能需要根据参数进行调整 - 但尝试一下现在...)
回答by alex
This answermay be helpful. In summary, to achieve the desired effect, you have to do the following things:
这个答案可能会有所帮助。综上所述,要达到想要的效果,必须做到以下几点:
- Redirect all I/O on the remote nohup'ed command
- Tell your local SSH command to exit as soon as it's done starting the remote process(es).
- 重定向远程 nohup 命令上的所有 I/O
- 告诉您的本地 SSH 命令在启动远程进程后立即退出。
Quoting the answer I already mentioned, in turn quoting wikipedia:
Nohuping backgrounded jobs is for example useful when logged in via SSH, since backgrounded jobs can cause the shell to hang on logout due to a race condition [2]. This problem can also be overcome by redirecting all three I/O streams:
nohup myprogram > foo.out 2> foo.err < /dev/null &
例如,当通过 SSH 登录时,Nohuping 后台作业很有用,因为后台作业可能会导致 shell 由于竞争条件而在注销时挂起 [2]。这个问题也可以通过重定向所有三个 I/O 流来克服:
nohup myprogram > foo.out 2> foo.err < /dev/null &
UPDATE
更新
I've just had success with this pattern:
我刚刚用这种模式取得了成功:
ssh -f user@host 'sh -c "( (nohup command-to-nohup 2>&1 >output.file </dev/null) & )"'
回答by wajiii
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:
设法解决了这个用例,我需要使用类似于此处其他答案的技术通过 ssh 远程启动后台脚本,但在某种程度上我觉得更简单和干净(至少,它使我的代码更短,并且——我相信 - 更好看),通过使用流关闭重定向语法显式关闭所有三个流(如以下位置所述:
https://unix.stackexchange.com/questions/131801/closing-a-file-descriptor-vs
https://www.gnu.org/software/bash/manual/html_node/Redirections.html
https://unix.stackexchange.com/questions/131801/closure-a-file-descriptor-vs
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:
而不是更广泛使用但(恕我直言)hackier“重定向到/从/ dev / null”,导致看似简单:
nohup script.sh >&- 2>&- <&-&
2>&1works 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. :)
2>&1效果与 2>&- 一样好,但我觉得后者更加清晰。;) 大多数人可能在最后的“后台工作”与号之前有一个空格,但由于它不是必需的(因为与号本身在正常使用中的作用就像一个分号),我更愿意省略它。:)

