编写Shell脚本以ssh到远程计算机并执行命令


97

我有两个问题:

  1. 有多台远程linux机器,我需要编写一个shell脚本,该脚本将在每台机器上执行相同的命令集。(包括一些sudo操作)。如何使用Shell脚本来完成?
  2. 切换到远程计算机时,提示输入RSA指纹认证时如何处理。

远程机器是在运行中创建的VM,我只有它们的IP。因此,我无法事先在这些计算机中放置脚本文件并从我的计算机中执行它们。


我考虑在远程Linux机器中部署类似代理的程序,该机器通过网络套接字(或SSL)连接/通过定期轮询服务器来维护与服务器的连接。
猛禽

我只需要执行一次命令集,因此不需要维护连接
Balanivash12年

我想“没有脚本”意味着“根本没有文件”吗?您如何处理身份验证?您可以禁用主机指纹检查(请参阅我的答案),但是如果您尚未设置公钥/私钥,则仍会收到交互式密码提示。
Andreas Fester 2012年

1
安德烈亚斯:是的。完全没有文件。passwd提示符可以通过使用 expect` Expect?assword: ”`
Balanivash

Answers:


141

有多台远程linux机器,我需要编写一个shell脚本,该脚本将在每台机器上执行相同的命令集。(包括一些sudo操作)。如何使用Shell脚本来完成?

您可以使用ssh进行此操作,例如:

#!/bin/bash
USERNAME=someUser
HOSTS="host1 host2 host3"
SCRIPT="pwd; ls"
for HOSTNAME in ${HOSTS} ; do
    ssh -l ${USERNAME} ${HOSTNAME} "${SCRIPT}"
done

切换到远程计算机时,提示输入RSA指纹认证时如何处理。

您可以将StrictHostKeyChecking=no选项添加到ssh:

ssh -o StrictHostKeyChecking=no -l username hostname "pwd; ls"

这将禁用主机密钥检查,并将主机密钥自动添加到已知主机列表中。如果您不想将主机添加到已知主机文件中,请添加选项-o UserKnownHostsFile=/dev/null

请注意,这会禁用某些安全检查,例如,防止中间人攻击。因此,不应将其应用于安全敏感的环境中。


什么是脚本语言?您可以当然也呼吁ssh从任何shell脚本
安德烈亚斯溃烂

如果您还想执行CTRL + C并继续ssh到多台服务器怎么办?例如,在某些服务器中要求输入密码,而在另一些服务器中则不要求输入密码,因此脚本将卡在那里。有没有办法做-c做CTRL c或CTRL d?
Chanafot

5

有很多方法可以解决此问题。

我最喜欢的方法是在远程系统上安装http://pamsshagentauth.sourceforge.net/,同时还要安装自己的公用密钥。(找出在虚拟机上安装这些文件的方法,以某种方式安装了整个Unix系统,还有几个文件?)

转发ssh代理后,您现在无需密码即可登录到每个系统。

甚至更好的是,该pam模块将使用您的ssh密钥对对sudo进行身份验证,以便您可以根据需要以root(或任何其他用户)权限运行。

您无需担心主机密钥交互。如果输入的不是终端,那么ssh只会限制您转发代理和使用密码进行身份验证的能力。

您还应该研究Capistrano之类的软件包绝对环顾四周;它介绍了远程脚本。

各个脚本行可能看起来像这样:

ssh remote-system-name command arguments ... # so, for exmaple,
ssh target.mycorp.net sudo puppet apply

4

使用来安装sshpass, apt-get install sshpass然后编辑脚本并将Linux机器的IP,用户名和密码按相应的顺序放置。之后,运行该脚本。而已 !该脚本将在所有系统中安装VLC。

#!/bin/bash
SCRIPT="cd Desktop; pwd;  echo -e 'PASSWORD' | sudo -S apt-get install vlc"
HOSTS=("192.168.1.121" "192.168.1.122" "192.168.1.123")
USERNAMES=("username1" "username2" "username3")
PASSWORDS=("password1" "password2" "password3")
for i in ${!HOSTS[*]} ; do
     echo ${HOSTS[i]}
     SCR=${SCRIPT/PASSWORD/${PASSWORDS[i]}}
     sshpass -p ${PASSWORDS[i]} ssh -l ${USERNAMES[i]} ${HOSTS[i]} "${SCR}"
done

使用$ SSHPASS导出密码以避免在脚本中显示。参考:tecmint.com/…–
Hexy

2

如果您能够编写Perl代码,则应考虑使用Net :: OpenSSH :: Parallel

您将能够以声明的方式描述必须在每个主机中运行的操作,并且该模块将处理所有令人恐惧的细节。sudo还支持通过命令运行命令。


2

这项工作对我来说。

语法:ssh -i pemfile.pem user_name @ ip_address'command_1; 命令2; 命令3'

#! /bin/bash

echo "########### connecting to server and run commands in sequence ###########"
ssh -i ~/.ssh/ec2_instance.pem ubuntu@ip_address 'touch a.txt; touch b.txt; sudo systemctl status tomcat.service'

1

对于此类任务,我反复使用Ansible,它允许在多个容器或VM中复制一致的bash脚本。Ansible(更确切地说是Red Hat)现在具有一个附加的Web界面AWX,这是其商业Tower的开源版本。

Ansible:https
: //www.ansible.com/ AWX:https : //github.com/ansible/awx
Ansible Tower:商业产品,您可能会首先探索免费的开源AWX,而不是15天的免费试用塔之


1

在多台远程Linux机器中有多种执行命令或脚本的方法。一种简单,最简单的方法是通过pssh(并行ssh程序)

pssh:是一种用于在多个主机上并行执行ssh的程序。它提供的功能包括将输入发送到所有进程,将密码传递给ssh,将输出保存到文件以及超时。

示例和用法:

连接到host1和host2,并分别从其中打印“ hello,world”:

 pssh -i -H "host1 host2" echo "hello, world"

通过脚本在多个服务器上运行命令:

pssh -h hosts.txt -P -I<./commands.sh

用法并运行命令而不检查或保存主机密钥:

pssh -h hostname_ip.txt -x '-q -o StrictHostKeyChecking=no -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes' -i  'uptime; hostname -f'

如果文件hosts.txt具有大量条目,例如100,那么parallelism选项也可以设置为100,以确保命令同时运行:

pssh -i -h hosts.txt -p 100 -t 0 sleep 10000

选项
-I:读取输入并发送到每个ssh进程。
-P:告诉pssh在到达时显示输出。
-h:读取主机的文件。
-H: [user @] host [:port]用于单主机。
-i:在每个主机完成时显示标准输出和标准错误
-x args:传递额外的SSH命令行参数
-o选项:可用于以配置文件中使用的格式提供选项。(/ etc / ssh / ssh_config )(〜/ .ssh / config)
-p并行性:使用给定的数目作为并发连接的最大数目。-
q安静模式: 导致大多数警告和诊断消息被抑制。
-t:在给定的秒数后使连接超时。0表示pssh不会使任何连接超时

切换到远程计算机时,提示输入RSA指纹认证时如何处理。

禁用StrictHostKeyChecking以处理RSA身份验证提示。
-o StrictHostKeyChecking =否

资料来源:man pssh


0

这对我有用。我做了一个功能。把它放在你的shell脚本中:

sshcmd(){
    ssh $1@$2 $3
}

sshcmd USER HOST COMMAND

如果要在多台计算机上执行相同的命令,请使用半冒号重复该行。例如,如果您有两台计算机,则可以执行以下操作:

sshcmd USER HOST COMMAND ; sshcmd USER HOST COMMAND

用计算机用户替换USER。将HOST替换为计算机的名称。将COMMAND替换为您要在计算机上执行的命令。

希望这可以帮助!


-1

您可以遵循以下方法:

  • 使用Expect Script连接到远程计算机。如果您的计算机不支持期望,则可以下载相同的计算机。编写Expect脚本非常容易(Google可以在此方面获得帮助)
  • 将需要在远程服务器上执行的所有操作放入外壳脚本中。
  • 登录成功后,从Expect脚本调用远程Shell脚本。

正如我在问题中提到的那样,远程计算机是在运行时创建的,因此我无法在计算机中预先拥有任何脚本。
Balanivash12年

在这种情况下,请将所有操作放在Expect脚本中。Expect脚本也可以在远程主机上运行命令。
rai.skumar 2012年
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.