我已经有一个ssh代理设置,我可以在外部服务器上运行命令在Bash脚本做这样的事情:

ssh blah_server "ls; pwd;"

现在,我真正想做的是在外部服务器上运行大量长命令。把所有这些都放在引号之间会很难看,为了避免这种情况,我真的宁愿避免多次ssh。

有没有一种方法可以一次性完成,用括号括起来?我想要的是:

ssh blah_server (
   ls some_folder;
   ./someaction.sh;
   pwd;
)

基本上,我对任何解决方案都很满意只要它是干净的。

Edit

为了澄清,我说的是这是一个更大的bash脚本的一部分。其他人可能需要处理脚本,所以我希望它保持干净。我不想有一个bash脚本与一行看起来像:

ssh blah_server "ls some_folder; ./someaction.sh 'some params'; pwd; ./some_other_action 'other params';"

因为它极其丑陋,难以阅读。


当前回答

我认为有两种方法:

首先,像这样创建一个控制套接字:

 ssh -oControlMaster=yes -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip>

运行你的命令

 ssh -oControlMaster=no -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip> -t <yourcommand>

通过这种方式,您可以编写ssh命令,而不必实际重新连接到服务器。

第二种方法是动态生成脚本,扫描脚本并运行。

其他回答

配置系统使用单ssh会话的最简单方法是默认使用多路复用。

这可以通过为套接字创建一个文件夹来完成:

mkdir ~/.ssh/controlmasters

然后将以下内容添加到您的.ssh配置中:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/controlmasters/%r@%h:%p.socket
    ControlMaster auto
    ControlPersist 10m

现在,您不需要修改任何代码。这允许在不创建多个会话的情况下对ssh和scp进行多次调用,这在本地和远程机器之间需要更多交互时非常有用。

感谢@terminus的回答,http://www.cyberciti.biz/faq/linux-unix-osx-bsd-ssh-multiplexing-to-speed-up-ssh-connections/和https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing。

把所有的命令放在一个脚本上,它可以像这样运行

ssh <remote-user>@<remote-host> "bash -s" <./remote-commands.sh

对于简单的命令,您可以使用:

ssh <ssh_args> command1 '&&' command2

or

ssh <ssh_args> command1 \&\& command2

使用多行字符串和多个bash脚本发布的答案不适合我。

长多行字符串很难维护。 单独的bash脚本不维护局部变量。

下面是一种实用的ssh和运行多个命令的方法,同时保持本地上下文。

LOCAL_VARIABLE=test

run_remote() {
    echo "$LOCAL_VARIABLE"
    ls some_folder; 
    ./someaction.sh 'some params'
    ./some_other_action 'other params'
}

ssh otherhost "$(set); run_remote"

在本地编辑脚本,然后将其导入ssh。

cat commands-to-execute-remotely.sh | ssh blah_server

command -to-execute-remote .sh看起来像上面的列表:

ls some_folder
./someaction.sh
pwd;