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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 17:34:56  来源:igfitidea点击:

Getting ssh to execute a command in the background on target machine

bashsshcsh

提问by dagorym

This is a follow-on question to the How do you use ssh in a shell script?question. If I want to execute a command on the remote machine that runs in the background on that machine, how do I get the ssh command to return? When I try to just include the ampersand (&) at the end of the command it just hangs. The exact form of the command looks like this:

这是如何在 shell 脚本中使用 ssh?题。如果我想在该机器后台运行的远程机器上执行命令,我如何让 ssh 命令返回?当我尝试在命令末尾包含与号 (&) 时,它只是挂起。命令的确切形式如下所示:

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

Any ideas? One thing to note is that logins to the the target machine always produce a text banner and I have SSHkeys set up so no password is required.

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

回答by Jax

I had this problem in a program I wrote a year ago -- turns out the answer is rather complicated. You'll need to use nohup as well as output redirection, as explained in the wikipedia artcle on nohup, copied here for your convenience.

我在一年前写的一个程序中遇到了这个问题——结果证明答案相当复杂。您需要使用 nohup 以及输出重定向,如维基百科文章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 &

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

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

回答by Russ

This has been the cleanest way to do it for me:-

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

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

The only thing running after this is the actual command on the remote machine

在此之后唯一运行的是远程机器上的实际命令

回答by AskApache Webmaster

Redirect fd's

重定向 fd

Output needs to be redirected with &>/dev/nullwhich redirects both stderr and stdout to /dev/null and is a synonym of >/dev/null 2>/dev/nullor >/dev/null 2>&1.

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

Parantheses

括号

The best way is to use sh -c '( ( command ) & )'where command is anything.

最好的方法是使用sh -c '( ( command ) & )'where 命令是任何东西。

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

Nohup Shell

Nohup 壳牌

You can also use nohup directly to launch the shell:

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

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

Nice Launch

不错的发布

Another trick is to use nice to launch the command/shell:

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

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

回答by hometoast

If you don't/can't keep the connection open you could use screen, if you have the rights to install it.

如果您不/不能保持连接打开,您可以使用screen,如果您有权安装它。

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 &

To detach the screen session: ctrl-ad

要分离屏幕会话: ctrl-ad

To list screen sessions:

列出屏幕会话:

screen -ls

To reattach a session:

要重新附加会话:

screen -d -r remote-command

Note that screen can also create multiple shells within each session. A similar effect can be achieved with tmux.

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

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

To detach the tmux session: ctrl-bd

分离 tmux 会话: ctrl-bd

To list screen sessions:

列出屏幕会话:

tmux list-sessions

To reattach a session:

要重新附加会话:

tmux attach <session number>

The default tmux control key, 'ctrl-b', is somewhat difficult to use but there are several example tmux configs that ship with tmux that you can try.

默认的 tmux 控制键“ ctrl-b”使用起来有些困难,但是您可以尝试使用 tmux 附带的几个示例 tmux 配置。

回答by cmcginty

I just wanted to show a working example that you can cut and paste:

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

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

回答by neil

Quickest and easiest way is to use the 'at' command:

最快和最简单的方法是使用“at”命令:

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

ssh user@target "现在 -f /home/foo.sh"

回答by neil

I think you'll have to combine a couple of these answers to get what you want. If you use nohup in conjunction with the semicolon, and wrap the whole thing in quotes, then you get:

我认为你必须结合这些答案中的几个才能得到你想要的。如果您将 nohup 与分号结合使用,并将整个内容用引号括起来,那么您将得到:

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

which seems to work for me. With nohup, you don't need to append the & to the command to be run. Also, if you don't need to read any of the output of the command, you can use

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

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

to redirect all output to /dev/null.

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

回答by fs82

This worked for me may times:

这可能对我有用:

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

回答by user889030

You can do it like this...

你可以这样做...

sudo /home/script.sh -opt1 > /tmp/script.out &

回答by PaulT

Actually, whenever I need to run a command on a remote machine that's complicated, I like to put the command in a script on the destination machine, and just run that script using ssh.

实际上,每当我需要在复杂的远程机器上运行命令时,我喜欢将命令放在目标机器上的脚本中,然后使用 ssh 运行该脚本。

For example:

例如:

# simple_script.sh (located on remote server)

#!/bin/bash

cat /var/log/messages | grep <some value> | awk -F " " '{print }'

And then I just run this command on the source machine:

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

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