如何编写多个ssh和scp命令到不同的系统

我想编写一系列涉及多个sshscp调用的命令。 我每天都会自己手动执行这个任务:

从LOCAL系统,ssh到SYSTEM1
mkdir / tmp / data在SYSTEM1上
从SYSTEM1,ssh到SYSTEM2
SYSTEM2上的mkdir / tmp / data
从SYSTEM2,SSH到SYSTEM3

从SYSTEM3:/ data到SYSTEM2:/ tmp / data的scp文件
退出到SYSTEM2
从SYSTEM2:/ data和SYSTEM2:/ tmp / data到SYSTEM1:/ tmp / data的scp文件
rm -fr SYSTEM2:/ tmp / data
退出到SYSTEM1
从SYSTEM1:/ data和SYSTEM1:/ tmp / data到本地:/ data的scp文件
rm -fr SYSTEM1:/ tmp / data

我每天至less做一次这个过程,在不同的系统之间需要大约5-10分钟的时间,然后再进行清理。 我真的想在bash脚本中自动化这个,但是到目前为止我的业余尝试都没有成功。 正如您可能会怀疑的那样,系统通信受到限制,这意味着LOCAL只能看到System1,System2只能看到System1和System3,system3只能看到system2等等。 做这个的最好方式是什么? 此外,System1是许多其他系统的集线器,因此SYSTEM2必须由用户指定(与任何SYSTEM2相比,System3始终具有相同的相对IP /主机名)。

我试着把这些命令按照正确的顺序放在一个shell脚本中,然后在提示时手动input密码(这已经是一个巨大的效率增益),但是这个方法不起作用,或者我的脚本执行是错误的。 此外,我想要一个脚本的命令行参数,将采取“system2”连接的模式,要复制的数据模式,以及本地系统上的数据的目标位置。

./grab_data system2 *05-14* ~/grabbed-data 

我做了一些search,我想我的下一步将是在每个系统上执行本地任务的脚本,然后通过各自的远程系统的ssh命令执行脚本。 有没有更好的办法? 我应该看看使用哪些命令,以及将这种嵌套的ssh和scp问题自动化的一般方法是什么?

我意识到我的描述可能有点复杂,所以请澄清我没有正确描述的任何领域。

谢谢。

Solutions Collecting From Web of "如何编写多个ssh和scp命令到不同的系统"

通过在其他ssh连接上隧道ssh连接,你可以简化这个过程(见前面的答案 )。 我这样做的方法是在LOCAL系统上用下列条目创建一个.ssh / config文件:

 Host SYSTEM3 ProxyCommand ssh -e none SYSTEM2 exec /usr/bin/nc %h %p 2>/dev/null HostName SYSTEM3.full.domain User system3user Host SYSTEM2 ProxyCommand ssh -e none SYSTEM1 exec /usr/bin/nc %h %p 2>/dev/null HostName SYSTEM2.full.domain User system2user Host SYSTEM1 HostName SYSTEM1.full.domain User system1user 

(假设两个中间主机都安装了netcat作为/ usr / bin / nc – 如果没有,你可能需要找到/安装一些stdin和标准输入到TCP会话的等效方法。)

通过这个设置,你可以在本地使用scp SYSTEM3:/data /data ,它会自动通过SYSTEM1和SYSTEM2(并且要求三个SYSTEMn的密码依次 – 这可能有点混乱,尤其是如果你错误输入一个)。

如果要连接到多个系统,特别是如果必须通过中间主机转发连接,则需要使用启用了ssh-agent转发的公钥身份验证。 这样,你只需要验证一次。

如果您只需要从远程命令中检查退出状态,那么使用代理转发的脚本SSH就足够了,但是如果您要做复杂的事情,最好使用expect或expect-lite来驱动SSH / SCP会议以更灵活的方式进行。 特别期待着被设计成交互式会话的强大替代品。

如果你坚持使用shell脚本,并且你的文件名改变了很多,你总是可以创建一个围绕SSH或者SCP的包装:

 # usage: my_ssh [remote_host] [command_line] # returns: exit status of remote command, or 255 on SSH error my_ssh () { local host="$1" shift ssh -A "$host" "$@" } 

在ssh-agent和包装函数之间,你应该有一个合理的起点来做你自己的努力。

另一种方法是使用rsync,它可以创建任何需要的目录,如果需要的话,可以删除复制的源文件。

在你的情况下,你可以使用这些命令

 home:~$ ssh system1 system1:~$ ssh system2 system2:~$ rsync -aPSHiv system3:/data /tmp/data system2:~$ exit system1:~$ rsync -aPSHiv --remove-source-files system2:/tmp/data /tmp/data system1:~$ rsync -aPSHiv system2:/data /tmp/data system1:~$ exit home:~$ rsync -aPSHiv --remove-source-files system1:/tmp/data /tmp/data home:~$ rsync -aPSHiv system1:/data /data 

如果你把这个和Gordon的方法结合起来,你甚至可以把它减少到

 home:~$ rsync -aPSHiv system1:/data/ system2:/data/ system3:/data/ /data/ 

请注意, rsync使...data...data/之间有所区别 – 前者表示目录及其内容,后者仅表示内容。 如果混合起来,可能会以另一个目录data中的目录data

此外,如果使用公共SSH密钥而不是密码,则可以简化这些操作。

我会使用以下任一项:

傀儡 – 配置管理工具,而不是配置!

厨师 – 与傀儡一样,在少数事情上只有更多的灵活性,少数其他的事情更少

终结者终端,它允许您并行连接到多个主机,并向选定的一组主机广播相同的命令