让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/null
redirect,它将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;程序执行&”