我已经有一个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';"

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


当前回答

使用多行字符串和多个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"

其他回答

如何使用Bash Here文档:

ssh otherhost << EOF
  ls some_folder; 
  ./someaction.sh 'some params'
  pwd
  ./some_other_action 'other params'
EOF

为了避免@Globalz在评论中提到的问题,您可以(取决于您在远程站点上做什么)将第一行替换为

ssh otherhost /bin/bash << EOF

注意,您可以在Here文档中进行变量替换,但可能必须处理引用问题。例如,如果您引用“限制字符串”(即。EOF),那么你就不能做变量替换。但是不引用极限字符串,变量被替换了。例如,如果您在shell脚本中定义了上面的$NAME,您可以这样做

ssh otherhost /bin/bash << EOF
touch "/tmp/${NAME}"
EOF

它会在目标主机上创建一个文件,文件的名称与你分配给$ name的名称相同。关于shell脚本引用的其他规则也适用,但太复杂了,这里不详细介绍。

为了匹配示例代码,可以将命令包装在单引号或双引号中。例如

ssh blah_server "
  ls
  pwd
"

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

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

这也可以按照以下方法完成。 将命令放到脚本中,我们将其命名为commands-inc.sh

#!/bin/bash
ls some_folder
./someaction.sh
pwd

保存文件

现在在远程服务器上运行它。

ssh user@remote 'bash -s' < /path/to/commands-inc.sh

我从来没有失败过。

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

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

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

ls some_folder
./someaction.sh
pwd;