这是一个后续的问题,你如何使用ssh在一个shell脚本?的问题。如果我想在远程机器上执行在后台运行的命令,如何返回ssh命令?当我试图在命令末尾只包含&号时,它就挂起了。命令的确切形式如下所示:
ssh user@target "cd /some/directory; program-to-execute &"
什么好主意吗?需要注意的一件事是,登录到目标机器总是产生一个文本横幅,我设置了SSH密钥,所以不需要密码。
这是一个后续的问题,你如何使用ssh在一个shell脚本?的问题。如果我想在远程机器上执行在后台运行的命令,如何返回ssh命令?当我试图在命令末尾只包含&号时,它就挂起了。命令的确切形式如下所示:
ssh user@target "cd /some/directory; program-to-execute &"
什么好主意吗?需要注意的一件事是,登录到目标机器总是产生一个文本横幅,我设置了SSH密钥,所以不需要密码。
当前回答
对我来说,使用tmux new -d <shell cmd>语法进行远程tmux会话似乎非常方便:
ssh someone@elsewhere 'tmux new -d sleep 600'
这将在其他主机上启动新会话,本地机器上的ssh命令将几乎立即返回shell。然后您可以通过ssh连接到远程主机,并将tmux附加到该会话。注意,没有本地tmux运行,只有远程运行!
另外,如果你想让你的会话在任务完成后继续,只需在命令后添加一个shell启动器,但不要忘记用引号括起来:
ssh someone@elsewhere 'tmux new -d "~/myscript.sh; bash"'
其他回答
我试图做同样的事情,但增加了复杂性,我试图从Java来做。因此,在一台运行java的机器上,我试图在另一台机器上运行一个脚本,在后台(使用nohup)。
从命令行,这里是工作的:(如果你不需要ssh到主机,你可能不需要“-i keyFile”)
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.
它花了一些试验和错误来让它工作,但现在似乎工作得很好。
If you run remote command without allocating tty, redirect stdout/stderr works, nohup is not necessary. ssh user@host 'background command &>/dev/null &' If you use -t to allocate tty to run interactive command along with background command, and background command is the last command, like this: ssh -t user@host 'bash -c "interactive command; nohup backgroud command &>/dev/null &"' It's possible that background command doesn't actually start. There's race here: bash exits after nohup starts. As a session leader, bash exit results in HUP signal sent to nohup process. nohup ignores HUP signal. If 1 completes before 2, the nohup process will exit and won't start the background command at all. We need to wait nohup start the background command. A simple workaroung is to just add a sleep: ssh -t user@host 'bash -c "interactive command; nohup backgroud command &>/dev/null & sleep 1"'
这个问题在几年前就被提出和回答了,我不知道openssh的行为从那时起是否发生了变化。我在测试: OpenSSH_8.6p1, OpenSSL 1.1.1g FIPS 21 Apr 2020
你可以这样做……
sudo /home/script.sh -opt1 > /tmp/script.out &
首先遵循以下步骤:
以用户A登录A,生成一对认证密钥。不要输入密码:
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创建一个目录~/。(目录可能已经存在,这没有问题):
a@A:~> ssh b@B mkdir -p .ssh
b@B's password:
最后将a的新公钥追加到b@B:。Ssh /authorized_keys最后一次输入b的密码:
a@A:~> cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
b@B's password:
从现在开始,你可以以B的身份从A以A的身份登录到B,无需密码:
a@A:~> ssh b@B
这样就可以不用输入密码了
ssh b@B "cd /some/目录;program-to-execute &”
这对我来说很有效:
ssh -x remoteServer "cd yourRemoteDir; ./yourRemoteScript.sh </dev/null >/dev/null 2>&1 & "