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

时间:2020-03-05 18:43:34  来源:igfitidea点击:

这是"如何在Shell脚本中使用ssh"的后续问题。问题。如果要在在后台计算机上运行的远程计算机上执行命令,如何获取ssh命令以返回?当我尝试在命令末尾仅包含&符时,它就会挂起。该命令的确切形式如下所示:

ssh user@target "cd /some/directory; program-to-execute &"

有任何想法吗?需要注意的一件事是,登录到目标计算机始终会生成文本横幅,并且我设置了SSH密钥,因此不需要密码。

解决方案

回答

我在一年前写的程序中遇到了这个问题-答案很复杂。我们将需要使用nohup以及输出重定向,如wikipedia中有关nohup的文章中所述,为方便起见,将其复制在此处。

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 &

回答

如果我们没有/无法保持连接的打开状态,那么我们可以使用屏幕,前提是我们有权安装它。

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 &

分离屏幕会话:ctrl-ad`

列出屏幕会话:

screen -ls

要重新添加会话:

screen -d -r remote-command

请注意,屏幕还可以在每个会话中创建多个外壳。使用tmux可以达到类似的效果。

user@localhost $ tmux
user@localhost $ ssh user@target # now inside of a tmux session
user@remotehost $ cd /some/directory; program-to-execute &

分离tmux会话:ctrl-bd`

列出屏幕会话:

tmux list-sessions

要重新添加会话:

tmux attach <session number>

默认的tmux控制键'ctrl-b'很难使用,但是tmux附带了一些示例tmux配置,我们可以尝试使用。

回答

我认为我们必须结合几个答案才能获得所需的内容。如果将nohup与分号结合使用,并将整个内容用引号引起来,则将得到:

ssh user@target "cd /some/directory; nohup myprogram > foo.out 2> foo.err < /dev/null"

这似乎对我有用。使用nohup,我们无需将&添加到要运行的命令上。另外,如果我们不需要读取命令的任何输出,则可以使用

ssh user@target "cd /some/directory; nohup myprogram > /dev/null 2>&1"

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

回答

这是为我做的最干净的方法:-

ssh -n -f user@host "sh -c 'cd /whereever; nohup ./whatever > /dev/null 2>&1 &'"

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

回答

我试图做同样的事情,但是增加了我尝试用Java进行的复杂性。因此,在一台运行Java的计算机上,我试图在后台(使用nohup)在另一台计算机上运行脚本。

在命令行中,这是起作用的方法:(如果不需要它,则不需要" -i keyFile"来SSH到主机)

ssh -i keyFile user@host bash -c "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\""

请注意,在我的命令行中,"-c"后面有一个参数,所有参数都用引号引起来。但是要使它在另一端运行,它仍然需要使用引号,因此我不得不在其中添加转义的引号。

从Java,这是有效的方法:

ProcessBuilder b = new ProcessBuilder("ssh", "-i", "keyFile", "bash", "-c",
 "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\"");
Process process = b.start();
// then read from process.getInputStream() and close it.

要使此功能正常运行,需要经过反复试验,但现在看来效果很好。