获取ssh以在目标计算机上的后台执行命令

dag*_*rym 282 ssh bash csh

这是关于如何在shell脚本中使用ssh的后续问题题.如果我想在该机器的后台运行的远程机器上执行命令,我该如何获取ssh命令?当我尝试在命令末尾包含&符号时,它就会挂起.命令的确切形式如下所示:

ssh user@target "cd /some/directory; program-to-execute &"
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?需要注意的一点是,登录目标计算机始终会生成文本标题,并且我已设置SSH密钥,因此无需密码.

Jax*_*Jax 298

我在一年前写的一个程序中遇到了这个问题 - 事实证明答案相当复杂.您需要使用nohup以及输出重定向,如nohup上的维基百科artcle中所述,为方便起见,将其复制到此处.

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

nohup myprogram > foo.out 2> foo.err < /dev/null &
Run Code Online (Sandbox Code Playgroud)

  • 在完成询问提示后,有关处理该流程的任何想法吗?(就像一个gpg - 已经完成了要求密码的解密) (2认同)
  • 你能解释一下`&lt; /dev/null`是什么意思吗?谢谢。 (2认同)
  • 同样来自维基百科关于 nohup 的文章:“另请注意,关闭 SSH 会话并不总是向相关进程发送 HUP 信号。其中,这取决于是否分配了伪终端。” 因此,虽然严格来说 nohup 可能并不总是需要,但从长远来看,使用它比不使用它更好。 (2认同)

小智 245

这对我来说是最干净的方式: -

ssh -n -f user@host "sh -c 'cd /whereever; nohup ./whatever > /dev/null 2>&1 &'"
Run Code Online (Sandbox Code Playgroud)

在此之后运行的唯一事情是远程计算机上的实际命令

  • `-n`不需要,因为`-f`意味着`-n` (7认同)
  • `ssh -f`将ssh进程连接起来,只是背景./ dev/null解决方案允许ssh快速断开连接,这可能是更好的选择. (6认同)

Ask*_*ter 30

重定向fd的

需要重定向输出&>/dev/null,将stderr和stdout重定向到/ dev/null并且是>/dev/null 2>/dev/null或的同义词>/dev/null 2>&1.

括号

最好的方法是使用sh -c '( ( command ) & )'命令是什么.

ssh askapache 'sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'
Run Code Online (Sandbox Code Playgroud)

Nohup Shell

您也可以直接使用nohup来启动shell:

ssh askapache 'nohup sh -c "( ( chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'
Run Code Online (Sandbox Code Playgroud)

不错的发布

另一个技巧是使用nice来启动命令/ shell:

ssh askapache 'nice -n 19 sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'
Run Code Online (Sandbox Code Playgroud)

  • 我知道这是你的一个非常古老的答案,但是你可以添加一些评论,为什么括号方式是最好的方式,添加`nohup`会产生什么(如果有的话)差异,以及为什么以及何时使用`nice`?我认为这会为这个答案增加很多. (8认同)

hom*_*ast 20

如果您没有/不能保持连接打开,您可以使用屏幕,如果您有权安装它.

user@localhost $ screen -t remote-command
user@localhost $ ssh user@target # now inside of a screen session
user@remotehost $ cd /some/directory; program-to-execute &
Run Code Online (Sandbox Code Playgroud)

要分离屏幕会话: ctrl-a d

列出屏幕会话:

screen -ls
Run Code Online (Sandbox Code Playgroud)

要重新连接会话:

screen -d -r remote-command
Run Code Online (Sandbox Code Playgroud)

请注意,屏幕还可以在每个会话中创建多个shell.使用tmux可以实现类似的效果.

user@localhost $ tmux
user@localhost $ ssh user@target # now inside of a tmux session
user@remotehost $ cd /some/directory; program-to-execute &
Run Code Online (Sandbox Code Playgroud)

要分离tmux会话: ctrl-b d

列出屏幕会话:

tmux list-sessions
Run Code Online (Sandbox Code Playgroud)

要重新连接会话:

tmux attach <session number>
Run Code Online (Sandbox Code Playgroud)

默认的tmux控制键' ctrl-b'有点难以使用,但有几个示例tmux配置随tmux一起提供,您可以尝试.

  • 怎么会使用`screen`呢? (2认同)

cmc*_*nty 18

我只是想展示一个可以剪切和粘贴的工作示例:

ssh REMOTE "sh -c \"(nohup sleep 30; touch nohup-exit) > /dev/null &\""
Run Code Online (Sandbox Code Playgroud)


ijt*_*ijt 14

您可以在不使用 nohup 的情况下执行此操作:

ssh user@host 'myprogram >out.log 2>err.log &'
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常低估的答案,谢谢! (2认同)
  • 这永远不会按预期工作(操作员要求的)。shell(以及 ssh)将等待后台进程终止。 (2认同)

小智 9

最快捷最简单的方法是使用'at'命令:

ssh user @ target"at now -f /home/foo.sh"

  • 您现在可以使用<<<,例如:ssh user @ target来模拟文件-f <<<'my_comnads'" (3认同)
  • 如果`at`在时间之后接受命令行参数而不仅仅是从文件中,这将是一个很好的通用解决方案. (2认同)

小智 6

我想你必须将这些答案结合起来才能得到你想要的东西.如果你将nohup与分号结合使用,并将整个内容包装在引号中,那么你得到:

ssh user@target "cd /some/directory; nohup myprogram > foo.out 2> foo.err < /dev/null"
Run Code Online (Sandbox Code Playgroud)

这似乎对我有用.使用nohup,您无需将&附加到要运行的命令.此外,如果您不需要读取命令的任何输出,则可以使用

ssh user@target "cd /some/directory; nohup myprogram > /dev/null 2>&1"
Run Code Online (Sandbox Code Playgroud)

将所有输出重定向到/ dev/null.


小智 5

这对我来说有用时间:

ssh -x remoteServer "cd yourRemoteDir; ./yourRemoteScript.sh </dev/null >/dev/null 2>&1 & " 
Run Code Online (Sandbox Code Playgroud)