21

我已经搜索了一些类似的问题,但除了运行一个命令或一些带有以下项目的命令之外:

ssh user@host -t sudo su -

但是,如果我基本上需要一次在(比方说)15 台服务器上运行脚本怎么办。这在 bash 中可行吗?在一个完美的世界中,如果可能的话,我需要避免安装应用程序。为了论证起见,假设我需要在 10 个主机上执行以下操作:

  1. 部署一个新的 Tomcat 容器
  2. 在容器中部署一个应用程序,并对其进行配置
  3. 配置 Apache 虚拟主机
  4. 重新加载 Apache

我有一个脚本可以完成所有这些工作,但它依赖于我登录所有服务器,从 repo 中提取一个脚本,然后运行它。如果这在 bash 中不可行,您有什么替代方案?我是否需要更大的锤子,例如 Perl(Python 可能是首选,因为我可以保证 Python 在 RHEL 环境中的所有机器上,这要归功于 yum/up2date)?如果有人可以向我指出任何有用的信息,我们将不胜感激,特别是如果它在 bash 中是可行的。我会满足于 Perl 或 Python,但我就是不知道这些(正在研究)。谢谢!

4

20 回答 20

11

您可以运行 che 和 Yang 所示的本地脚本,和/或您可以使用 Here 文档:

ssh root@server /bin/sh <<\EOF  
wget http://server/warfile    # Could use NFS here  
cp app.war /location  
command 1  
command 2  
/etc/init.d/httpd restart  
EOF 
于 2008-10-28T16:16:33.567 回答
10

通常,我只会使用 Expect 的原始 Tcl 版本。您只需要在本地计算机上安装它。如果我在使用 Perl 的程序中,我会使用Net::SSH::Expect来执行此操作。其他语言也有类似的“期望”工具。

于 2008-10-28T16:19:07.260 回答
9

如何在多台服务器上同时运行命令的问题前几天出现在 Perl 邮件列表中,我将给出与那里相同的建议,即使用gsh

http://outflux.net/unix/software/gsh

gsh 类似于已经给出for box in box1_name box2_name box3_name的 " " 解决方案,但我发现 gsh 更方便。您设置了一个 /etc/ghosts 文件,其中包含您的服务器组,例如 web、db、RHEL4、x86_64 或其他(man ghosts)组,然后在调用 gsh 时使用该组。

[pdurbin@beamish ~]$ gsh web "cat /etc/redhat-release; uname -r"
www-2.foo.com: Red Hat Enterprise Linux AS release 4 (Nahant Update 7)
www-2.foo.com: 2.6.9-78.0.1.ELsmp
www-3.foo.com: Red Hat Enterprise Linux AS release 4 (Nahant Update 7)
www-3.foo.com: 2.6.9-78.0.1.ELsmp
www-4.foo.com: Red Hat Enterprise Linux Server release 5.2 (Tikanga)
www-4.foo.com: 2.6.18-92.1.13.el5
www-5.foo.com: Red Hat Enterprise Linux Server release 5.2 (Tikanga)
www-5.foo.com: 2.6.18-92.1.13.el5
[pdurbin@beamish ~]$

例如,您还可以使用 web+db 或 web-RHEL4 组合或拆分幽灵组。

我还要提到,虽然我从未使用过 shmux,但它的网站包含一个软件列表(包括 gsh),可让您同时在多个服务器上运行命令。 Capistrano已经被提及并且(据我了解)也可能在该列表中。

于 2008-10-28T22:26:20.480 回答
6

看看期望 ( man expect)

我过去曾使用 Expect 完成过类似的任务。

于 2008-10-28T15:47:56.230 回答
5

您可以将本地脚本通过管道传输到远程服务器并使用一个命令执行它:

ssh -t user@host 'sh' < path_to_script

这可以通过使用公钥认证和用脚本包装来执行并行执行来进一步自动化。

于 2008-10-28T15:52:47.017 回答
4

你可以试试paramiko。这是一个纯 python ssh 客户端。您可以对 ssh 会话进行编程。无需在远程机器上安装任何东西。

请参阅这篇关于如何使用它的精彩文章。

于 2009-11-09T08:57:27.177 回答
3

为您提供结构,无需实际代码。

  1. 使用 scp 将您的安装/设置脚本复制到目标框。
  2. 使用 ssh 在远程机器上调用您的脚本。
于 2008-10-28T15:33:34.760 回答
2

pssh可能很有趣,因为与这里提到的大多数解决方案不同,这些命令是并行运行的。

(为了我自己的使用,我编写了一个更简单的小脚本,与 GavinCattell 的非常相似,它在此处记录 - 法语)。

于 2008-12-15T09:19:05.020 回答
2

您是否看过PuppetCfengine 之类的东西。他们可以做你想做的事,而且可能更多。

于 2008-12-15T09:53:55.997 回答
2

对于那些偶然发现这个问题的人,我将提供一个使用Fabric的答案,它完全解决了上述问题:Running absolute commands on multiple hosts over ssh。

安装 fabric 后,您将创建一个fabfile.py, 并实现可以在远程主机上运行的任务。例如,重新加载 Apache的任务可能如下所示:

from fabric.api import env, run

env.hosts = ['host1@example.com', 'host2@example.com']

def reload():
    """ Reload Apache """
    run("sudo /etc/init.d/apache2 reload")

然后,在您的本地计算机上运行fab reload,​​该sudo /etc/init.d/apache2 reload命令将在env.hosts.

于 2012-04-30T19:10:16.443 回答
1

虽然这是一个复杂的话题,但我强烈推荐Capistrano

于 2008-10-28T15:37:21.587 回答
1

您可以像以前一样执行此操作,只需编写脚本而不是手动执行。以下代码远程连接到名为“loca”的机器并在那里运行两个命令。您需要做的只是插入要在其中运行的命令。

che@ovecka ~ $ ssh loca 'uname -a; 回声某事_else'
Linux 本地 2.6.25.9 #1 (blahblahblah)
别的东西

然后,要遍历所有机器,请执行以下操作:

用于 box1_name 中的框 box2_name box3_name
做
   ssh $box 'commmands_to_run_everywhere'
完毕

为了使这个 ssh 事情在不输入密码的情况下一直工作,您需要设置密钥身份验证。您可以在IBM developerworks上了解它。

于 2008-10-28T15:43:36.723 回答
1

您可以使用cluster ssh之类的工具一次在多台服务器上运行相同的命令。该链接是关于 Debian 软件包每日博客上集群 ssh 的讨论。

于 2008-10-28T15:45:58.637 回答
1

好吧,对于第 1 步和第 2 步,没有 Tomcat 管理器 Web 界面;您可以使用带有 libwww 插件的 curl 或 zsh 编写脚本。

对于 SSH,您希望:1) 不会提示输入密码(使用密钥) 2) 在 SSH 的命令行上传递命令,这类似于rsh在受信任的网络中。

其他帖子已经向您展示了该怎么做,我可能也会使用sh,但我很想使用perllikessh tomcatuser@server perl -e 'do-everything-on-one-line;'或者您可以这样做:

要么 scp the_package.tbz tomcatuser@server:the_place/.
ssh tomcatuser@server /bin/sh <<\EOF
定义类似的东西, TOMCAT_WEBAPPS=/usr/local/share/tomcat/webapps
tar xj the_package.tbz 要么 rsync rsync://repository/the_package_place
mv $TOMCAT_WEBAPPS/old_war $TOMCAT_WEBAPPS/old_war.old
mv $THE_PLACE/new_war $TOMCAT_WEBAPPS/new_war
touch $TOMCAT_WEBAPPS/new_war[您通常不必重新启动tomcat]
mv $THE_PLACE/vhost_file $APACHE_VHOST_DIR/vhost_file
$APACHECTL restart[可能需要以apache用户身份登录才能移动该文件并重新启动]
EOF

于 2008-10-28T17:24:52.790 回答
1

您需要 DSH 或分布式 shell,它在集群中使用很多。这是链接:dsh

您基本上有节点组(其中包含节点列表的文件),并且您指定要在哪个节点组上运行命令,然后您将使用 dsh,就像您使用 ssh 在它们上运行命令一样。

dsh -a /path/to/some/command/or/script

它将同时在所有机器上运行该命令并返回带有主机名前缀的输出。命令或脚本必须存在于系统上,因此共享的 NFS 目录对这类事情很有用。

于 2008-10-29T14:38:11.813 回答
1

创建访问的所有机器的主机名 ssh 命令。通过 Quierati http://pastebin.com/pddEQWq2

#Use in .bashrc
#Use "HashKnownHosts no" in ~/.ssh/config or /etc/ssh/ssh_config 
# If known_hosts is encrypted and delete known_hosts

[ ! -d ~/bin ] && mkdir ~/bin
for host in `cut -d, -f1 ~/.ssh/known_hosts|cut -f1 -d " "`;
  do
    [ ! -s ~/bin/$host ] && echo ssh $host '$*' > ~/bin/$host
done
[ -d ~/bin ] && chmod -R 700 ~/bin
export PATH=$PATH:~/bin 

前执行:

$for i in hostname{1..10}; do $i who;done
于 2012-06-06T13:06:15.447 回答
1

有一个名为FLATT(灵活自动化和故障排除工具)的工具,它允许您通过单击按钮在多个 Unix/Linux 主机上执行脚本。它是一个在 Mac 和 Windows 上运行的桌面 GUI 应用程序,但也有一个命令行 java 客户端。
您可以创建批处理作业并在多个主机上重复使用。
需要 Java 1.6 或更高版本。

于 2013-09-17T20:35:04.620 回答
0

我不确定这种方法是否适用于你想要的一切,但你可以尝试这样的事情:

$ cat your_script.sh | ssh your_host bash

它将在远程服务器上运行脚本(位于本地)。

于 2008-10-29T17:00:16.503 回答
0

只需阅读一篇使用setsid的新博客,除了主流内核之外,无需任何进一步的安装/配置。在 Ubuntu14.04 下测试/验证。

虽然作者也有非常清晰的解释和示例代码,但这里有一个快速浏览的神奇部分:

#----------------------------------------------------------------------
# Create a temp script to echo the SSH password, used by SSH_ASKPASS
#----------------------------------------------------------------------
SSH_ASKPASS_SCRIPT=/tmp/ssh-askpass-script
cat > ${SSH_ASKPASS_SCRIPT} <<EOL
#!/bin/bash
echo "${PASS}"
EOL
chmod u+x ${SSH_ASKPASS_SCRIPT}

# Tell SSH to read in the output of the provided script as the password.
# We still have to use setsid to eliminate access to a terminal and thus avoid
# it ignoring this and asking for a password.
export SSH_ASKPASS=${SSH_ASKPASS_SCRIPT}
......
......
# Log in to the remote server and run the above command.
# The use of setsid is a part of the machinations to stop ssh 
# prompting for a password.
setsid ssh ${SSH_OPTIONS} ${USER}@${SERVER} "ls -rlt"
于 2014-08-28T19:54:31.430 回答
0

我发现无需安装或配置太多软件的最简单方法是使用普通的旧 tmux。假设您有 9 台 linux 服务器。选择一个盒子作为你的主要。启动一个 tmux 会话:

tmux

然后通过执行 8 次创建 9 个拆分 tmux 窗格:

ctrl-b + %

在此处输入图像描述

现在 SSH 进入每个窗格中的每个框。您需要了解一些 tmux 快捷方式。要导航,请按:

ctrl+b <arrow-keys>

一旦您登录到每个窗格上的所有框。现在打开窗格同步,它可以让您在每个框中键入相同的内容:

ctrl+b :setw synchronize-panes on

现在,当您按任意键时,它将显示在每个窗格上。要关闭它,只需打开关闭即可。要循环调整窗格大小,请按 ctrl+b <空格键>。

这对我来说效果更好,因为我需要查看每个终端输出,因为有时在下载或升级软件时服务器会因任何原因崩溃或挂起。任何问题,您都可以单独隔离和解决。

于 2020-04-20T16:10:08.020 回答