让ssh在目标机器的后台执行一个命令

这是一个关于如何在shell脚本中使用ssh的后续问题? 题。 如果我想在该机器的后台运行的远程机器上执行命令,如何获得ssh命令返回? 当我试图在命令的末尾添加&符号(&)时,它会挂起。 命令的确切forms如下所示:

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

有任何想法吗? 有一件事要注意的是,login到目标机器总是产生一个文本横幅,我有SSH密钥设置,所以不需要密码。

我在一年前写的一个程序中遇到了这个问题 – 事实certificate,答案相当复杂。 您将需要使用nohup以及输出redirect,如nohup上的wikipedia artcle所解释的,为了您的方便,在这里复制。

Nohuping后台作业在通过SSHlogin时非常有用,因为后台作业可能会导致shell在注销时由于竞争条件而挂起[2]。 这个问题也可以通过redirect所有三个I / Ostream来解决:

 nohup myprogram > foo.out 2> foo.err < /dev/null & 

这是为我做的最干净的方式:

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

在这之后运行的唯一事情就是远程机器上的实际命令

redirectfd的

输出需要用&>/dev/nullredirect,它将stderr和stdoutredirect到/ 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 ) & )"' 

Nohup壳牌

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

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

尼斯推出

另一个诀窍是使用nice来启动命令/ shell:

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

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

 ssh REMOTE "sh -c \"(nohup sleep 30; touch nohup-exit) > /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-a d

要列出屏幕会话:

 screen -ls 

重新安排会议:

 screen -d -r remote-command 

请注意,屏幕也可以在每个会话中创build多个shell。 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-b d

要列出屏幕会话:

 tmux list-sessions 

重新安排会议:

 tmux attach <session number> 

默认的tmux控制键“ ctrl-b ”有点难以使用,但是有几个tmuxconfiguration文件,你可以尝试使用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" 

将所有输出redirect到/ dev / null。

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

ssh user @ target“at -f /home/foo.sh”

这工作对我来说可能是时代:

 ssh -x remoteServer "cd yourRemoteDir; ./yourRemoteScript.sh </dev/null >/dev/null 2>&1 & " 

实际上,无论何时我需要在复杂的远程计算机上运行命令,我都希望将命令放在目标计算机上的脚本中,然后使用ssh运行该脚本。

例如:

 # simple_script.sh (located on remote server) #!/bin/bash cat /var/log/messages | grep <some value> | awk -F " " '{print $8}' 

然后我只是在源机器上运行这个命令:

 ssh user@ip "/path/to/simple_script.sh" 

我正在尝试做同样的事情,但增加了一些复杂性,我试图用Java来完成。 所以在运行java的一台机器上,我试图在另一台机器上运行脚本,在后台(使用nohup)。

从命令行,这是什么工作:(您可能不需要“-i密钥文件”,如果你不需要它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. 

为了得到这个工作,花了一些试验和错误,但现在似乎运行良好。

我认为这是你所需要的:首先你需要在你的机器上安装sshpass 。 那么你可以写你自己的脚本:

 while read pass port user ip; do sshpass -p$pass ssh -p $port $user@$ip <<ENDSSH1 COMMAND 1 . . . COMMAND n ENDSSH1 done <<____HERE PASS PORT USER IP . . . . . . . . . . . . PASS PORT USER IP ____HERE 

首先按照这个程序:

以用户a的身份loginA并生成一对authentication密钥。 不要input密码

 a@A:~> ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/a/.ssh/id_rsa): Created directory '/home/a/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/a/.ssh/id_rsa. Your public key has been saved in /home/a/.ssh/id_rsa.pub. The key fingerprint is: 3e:4f:05:79:3a:9f:96:7c:3b:ad:e9:58:37:bc:37:e4 a@A 

现在使用ssh创build一个目录〜/ .ssh作为B上的用户b(该目录可能已经存在,这很好):

 a@A:~> ssh b@B mkdir -p .ssh b@B's password: 

最后在b @ B:.ssh / authorized_keys中添加一个新的公钥,最后一次inputb的密码:

 a@A:~> cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys' b@B's password: 

从现在开始,你可以从Alogin到B,而不需要密码:

 a@A:~> ssh b@B 

那么这将工作,而不input密码

ssh b @ B“cd / some / directory;程序执行&”