7

我想通过 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 的连接已关闭。

这里有什么问题?

谢谢你的帮助

4

3 回答 3

6

您的命令在后台运行进程管道,因此调用脚本将立即退出(或很快退出)。这将导致 ssh 关闭连接。这反过来将导致 aSIGHUP被发送到连接到该-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 " &

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

于 2010-12-12T21:42:01.140 回答
5

这个答案可能会有所帮助。综上所述,要达到预期的效果,你必须做到以下几点:

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

引用我已经提到的答案,然后引用维基百科

例如,当通过 SSH 登录时,Nohuping 后台作业很有用,因为后台作业可能会导致 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) & )"'
于 2012-10-28T19:02:16.513 回答
-1

设法解决了一个用例,我需要使用类似于此处其他答案的技术通过 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

而不是更广泛使用但(恕我直言)hackier“重定向到/从/ dev / null”,导致看似简单:

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

2>&1和 2>&- 一样有效,但我觉得后者更加清晰。;) 大多数人可能在最后的“后台作业”& 符号之前有一个空格,但由于它不是必需的(因为 & 符号本身在正常使用中的功能就像分号),我更喜欢省略它。:)

于 2018-06-21T20:38:04.820 回答