在多台远程计算机上运行shell脚本

时间:2017-06-27 19:51:51

标签: bash

警告:使用bash shell脚本的新手。

我已经创建了连接到多个远程计算机的脚本,逐个检查某个文件是否已经包含某些文本,如果有,请移动到下一台计算机并进行相同的检查,如果不,将文本附加到文件,然后移动到下一台机器。

目前,脚本连接到第一台远程计算机,但在连接时不执行任何操作。如果我输入exit来关闭远程机器的连接,它会继续运行脚本,这对我没有好处,因为我已经不再连接到远程机器了。

在旁注上,我甚至不确定其余的代码是否正确,所以如果有任何明显的错误,请告诉我。这实际上是我从头开始编写shell脚本的第一次尝试。



#!/bin/bash

REMOTE_IDS=(    root@CENSOREDIPADDRESS1
                root@CENSOREDIPADDRESS2
                root@CENSOREDIPADDRESS3
                )

for REMOTE in "{$REMOTE_IDS[@]}"
do

ssh -oStrictHostKeyChecking=no $REMOTE_IDS

if grep LogDNAFormat "/etc/syslog-ng/syslog-ng.conf"
    then
        echo $REMOTE
        echo "syslog-ng already modified. Skipping."
        exit
        echo -
    else
        echo $REMOTE
        echo "Modifiying..."
        echo "\n" >> syslog-ng.conf
        echo "### START syslog-ng LogDNA Logging Directives ###" >> syslog-ng.conf
        echo "template LogDNAFormat { template(\"<key:CENSOREDKEY> <${PRI}>1 ${ISODATE} ${HOST} ${PROGRAM} ${PID} ${MSGID} - $MSG\n\");" >> syslog-ng.conf
        echo "template_escape(no);" >> syslog-ng.conf
        echo "};" >> syslog-ng.conf
        echo "destination d_logdna {" >> syslog-ng.conf
        echo "udp(\"syslog-a.logdna.com\" port(CENSOREDPORT)" >> syslog-ng.conf
        echo "template(LogDNAFormat));" >> syslog-ng.conf
        echo "};" >> syslog-ng.conf
        echo "log {" >> syslog-ng.conf
        echo "source(s_src);" >> syslog-ng.conf
        echo "destination(d_logdna);" >> syslog-ng.conf
        echo "};" >> syslog-ng.conf
        echo "### END syslog-ng LogDNA logging directives ###" >> syslog-ng.conf

        killall -s 9 syslog-ng
        sleep 5
        /etc/init.d/syslog start

        echo -
fi


done
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:2)

很棒的问题:通过ssh自动化程序是一个值得称道的目标。

让我们从代码中的第一个错误开始:

ssh -oStrictHostKeyChecking=no $REMOTE_IDS

应该是:

ssh -oStrictHostKeyChecking=no $REMOTE

但那也不会做任何事情。如果你想ssh运行一组命令,你可以,但是你需要将这些命令作为一个字符串传递给ssh。

ssh -oStrictHostKeyChecking=no $REMOTE 'Lots of code goes here - newlines ok'

要使其正常工作,您需要配置无密码ssh(或者提示您输入凭据)。这在Alexei Grochev的帖子中的步骤1)和2)中有所涉及。无密码登录的一个选项是将公钥放在要管理的主机上,如有必要,可以在本地〜/ .ssh / config中更改IdentityFile(如果使用默认公共/您可能不需要这样做)私钥对)。

你必须小心谨慎地窃取你的标准(我不认为你的情况会有问题)。如果您怀疑ssh命令正在读取所有stdin输入,那么您需要向ssh提供-n参数(同样,我认为您的代码不会遇到此问题,但我没有&#39 ;仔细看)。

我同意tadman的评论,这是Ansible的一个很好的应用程序。但是,我不会仅仅为这项任务学习Ansible。如果您打算进行大量的远程自动化,Ansible非常值得您花时间学习并应用这个问题。

我建议的是pssh和pscp。这些工具很棒,可以照顾&#34; for&#34;循环给你。他们还并行执行ssh调用并收集结果。

以下是我建议的步骤:

1)安装pssh(pscp随之而来)。 2)将您的bash程序写为单独的文件。如果您的程序不在一堆echo语句中,那么调试和更新等等就容易得多。那些伤害。甚至我原来建议使用ssh user @ host&#39;长串命令&#39;很难调试。只需创建一个在远程主机上运行的程序文件,并在远程主机上进行调试(尽可能)。 3)现在回到您的控制主机(使用该bash程序)。使用pscp将其推送到管理下的所有主机。语法如下:

# Your bash program is at <local-file-path>
chmod +x <local-file-path>
pscp -h<hosts-file>  -l root <local-file-path> <remote-file-path>

-h选项指定主机列表。所以看起来像这样:

CENSOREDIPADDRESS1
CENSOREDIPADDRESS2
CENSOREDIPADDRESS3

顺便提一下,如果你没有设置你的公钥/私钥,你可以指定-A参数,pscp和pssh会询问你root用户的密码。这对于自动化来说并不是很好,但如果您正在执行一次性任务,那么设置公钥/私钥要容易得多。

4)现在在远程主机上执行该程序:

pssh -h<hosts-file> -i <remote-file-path>

-i参数告诉pssh等待程序在所有主机上执行并返回stdout和stderr结果。

总之,对于像这样的小任务,pssh / pscp非常棒。对于较大的任务,请考虑Ansible(它基本上通过在ssh上发送python脚本并远程执行它们来工作)。 Puppet / Chef对此有点矫枉过正,但它们是保持数据中心处于您想要状态的绝佳工具。

答案 1 :(得分:1)

你可以用木偶/厨师做到这一点。

但是如果你有耐心,这也可以用bash来完成。我不想提供实际代码,因为我认为最好先了解逻辑。 但是,既然你问过,这是你应该遵循的流程:

  1. 确保您为所有计算机设置了密钥
  2. 使用所有服务器创建配置
  3. 将所有服务器放入数组
  4. 创建一个循环来调用每个框并运行你的脚本(在你必须将scp脚本放到盒子上的主目录之前,所以确保它运行良好)
  5. 你也可以做你想要的更好的事情,以及我之前做过的事情。

    1)创建一个脚本来读取你的文件并把它放在cron上运行每分钟或任何时间最好,比如把文件的#size回显到日志文件 2)所有服务器都将运行这些脚本,所以现在只需运行脚本来获取所有服务器上的数据(遍历配置文件中的服务器阵列)

    ^^那里也可以用php完成,你有一个webserver实例读取文件。你也可以创建一个带有bash的web服务器...因为它只用于1个任务,所以它并不是非常疯狂。

    玩得开心。