如何通过ssh在远程计算机上运行本地bash脚本?


51

我正在寻找一种将配置从一台中央计算机推送到多台远程计算机的方法,而无需在远程计算机上安装任何东西。

目的是在没有cfengine设置代理的一组机器上执行类似的工具,就像您会发现的那样。实际上,这可能是cfagent在一组现有远程计算机上进行设置的好方法。



1
实际问题有23个投票,其中SO上的重复有55:P
MoJo

Answers:


55

您可以传递脚本并通过管道化它并执行一个shell使其暂时执行。

例如

echo "ls -l; echo 'Hello World'" | ssh me@myserver /bin/bash

自然,"ls -l; echo 'Hello World'"可以用存储在本地计算机上文件中的bash脚本替换零件。

例如

cat script.sh | ssh me@myserver /bin/bash

干杯!


2
我如何使它在远程系统上以sudo的身份运行。例如,如果我在远程服务器上登录,则通常以sudo -u testuser script.sh
Sharjeel 2013年

如果我正在调用的脚本涉及用户交互,该怎么办?
Abhimanyu Srivastava

20

有几种方法可以做到这一点。

1:

ssh user@remote_server 'bash -s' < localfile

2:

cat localfile  | ssh user@remote_server

3:

ssh user@remote_server "$(< localfile)"

3是我的首选方式,它允许交互式命令,例如 su -S service nginx restart

(使用时,#1将使用脚本的其余部分作为密码问题的输入su -S。)


4
关于在远程计算机上运行本地脚本-有没有办法将变量作为参数发送到远程计算机。即与脚本一起,我想将变量(具有多行)作为参数发送到远程计算机。然后,脚本打算使用该变量。

13

我会为此推荐python的Fabric:

#!/usr/bin/python
# ~/fabfile.py

from fabric_api import *

env.hosts = ['host1', 'host2']
def deploy_script():
    put('your_script.sh', 'your_script.sh', mode=0755)
    sudo('./your_script.sh')

# from shell
$ fab deploy_script

您应该可以使用以上内容开始使用。请查阅Fabric的出色文档来完成其余工作。作为附录,完全可以完全在Fabric中编写脚本-无需复制,但是应注意,要在所有计算机上更改脚本,只需要编辑本地副本并重新部署即可。此外,除了API的基本用法外,您还可以根据脚本当前在哪个主机上运行和/或其他变量来修改脚本。这是一种pythonic Expect。


我认为这不能完全解决问题,但是我喜欢这个主意,可以将Fabric视为有用的工具。
tremoloqui 2010年

1
@tremoloqui Fabric是ssh的python包装器-目标计算机上无需安装任何东西,只需保存脚本即可。如果将其重写为一系列Fabric命令(使用runsudo),则甚至不需要。
Izkata 2012年

5

这正是Ansible的用途。没有代理,您只需要创建一个文本文件即可:

/etc/ansible/hosts

内容类似于:

[webhosts]
web[1-8]

这将指定机器“ web1,web2 ... web8”在“ webhosts”组中。然后,您可以执行以下操作:

ansible webhosts -m service -a "name=apache2 state=restarted" --sudo

使用sudo在所有机器上重新启动apache2服务。

您可以执行以下命令:

ansible webhosts -m shell -a "df -h"

或者您可以在远程计算机上运行本地脚本:

ansible webhosts -m script -a "./script.sh"

或者,您也可以创建一个具有完整配置的剧本(查看文档以了解详细信息),以使服务器符合并进行配置:

ansible-playbook webplaybook.yml

基本上,您可以开始将其用作在多台服务器上运行命令的命令行工具,并根据需要将其用法扩展到完整的配置工具中。


3
我和下一个家伙一样喜欢ansible,但是如果他问一个脚本,那么ansible有一个非常不错的脚本模块ansible webhosts -m script script.sh
ptman

1
所有其他答案都涉及bash脚本,但这不是他明确要求的。他只是说将配置推送到远程计算机。但脚本模块非常值得一提:)
seumasmac

请对此答案投票!这是这样做的方法!
小鸡

@ptman我只是注意到,虽然他在问题中没有提到脚本,但在标题中却提到了!抱歉。我已经更新了。
seumasmac

3

正如在解释这个答案,你可以使用定界符

ssh user@host <<'ENDSSH'
#commands to run on remote host
ENDSSH

您必须谨慎使用Heredoc,因为它只是发送文本,但实际上并没有等待响应。这意味着它不会等待命令执行。


1

如果您尝试使用或在远程Linux计算机上运行脚本,则此处的答案(https://stackoverflow.com/a/2732991/4752883)非常有用。如果脚本上有多行,它将起作用。plinksshlinux

**但是,如果您尝试运行位于本地linux/windows计算机上的批处理脚本,而您的远程计算机是Windows,并且使用**由多行组成

plink root@MachineB -m local_script.bat

它不会工作。

仅脚本的第一行将被执行。这可能是的限制plink

解决方案1:

要运行多行批处理脚本(尤其是如果它相对简单一些,则由几行组成):

如果您的原始批处理脚本如下

cd C:\Users\ipython_user\Desktop 
python filename.py

您可以使用文件中的“ &&”分隔符将这些行组合在一起,如下 local_script.bat所示 :https : //stackoverflow.com/a/8055390/4752883

cd C:\Users\ipython_user\Desktop && python filename.py

进行此更改后,您可以按照@ JasonR.Coombs此处指出的那样运行脚本:https ://stackoverflow.com/a/2732991/4752883

解决方案2:

如果您的批处理脚本相对复杂,则最好使用封装plink命令的批处理脚本以及@Martin https://stackoverflow.com/a/32196999/4752883在此处指出的以下命令:

rem Open tunnel in the background
start plink.exe -ssh [username]@[hostname] -L 3307:127.0.0.1:3306 -i "[SSH
key]" -N

rem Wait a second to let Plink establish the tunnel 
timeout /t 1

rem Run the task using the tunnel
"C:\Program Files\R\R-3.2.1\bin\x64\R.exe" CMD BATCH qidash.R

rem Kill the tunnel
taskkill /im plink.exe

0

为什么不先复制脚本,然后再运行它呢?

scp your_script.sh the_server:
ssh the_server "chmod +x your_script.sh; ./your_script.sh"

当然,您应该小心,不要将其上传到世界可写的地方,这样,在您运行它(可能是root用户)之前,没有其他人可以弄弄它。


1
我不想上载脚本的原因是,它不必进行管理,也没有您提到的风险。另外,在我看来,它比上载,处理和(可选)删除的多步骤过程更简单。
tremoloqui 2010年

0

重写,在它的每个命令已经是一个方法脚本前缀ssh和主机名/ IP或这样的列表被传递给脚本作为参数(假设你有密码的/的ssh-agent密钥验证设置)。为了从远程命令中正确传回错误/返回码,可能需要做一些工作。


0

如果脚本不是太大,并且您正在使用bash或ksh ...

ssh vm24 -t bash -c "$(printf "%q" "$(< shell-test.sh )")"

stdin和stdout都可以正常工作,但是脚本限于参数大小(通常为100k)。该脚本的参数可能在该行的末尾起作用,可能在附加的“-”参数之后。分配pty的“ -t”是可选的。

当心:这会混淆bash的完成,请不要点击tab。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.