ssh到aws服务器并编辑hosts文件

时间:2014-01-10 23:35:33

标签: python python-2.7 amazon-web-services ssh boto

我的代码:

出于某种原因,这似乎是无限循环并重复打印'here2'和'ls -lah'的输出。有什么东西出血明显我做错了吗?

def update_hosts_file(public_dns,hosts_file_info):
    for dns in public_dns:
        print 'here2'
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # wont require saying 'yes' to new fingerprint
        key_path = os.path.join(os.path.expanduser(KEY_DIR), KEY_NAME)+'.pem'
        ssh.connect(dns,username='ubuntu',key_filename=key_path)
        ssh.exec_command('touch testing')
        a,b,c=ssh.exec_command("ls -lah")
        print b.readlines()
        a,b,c=ssh.exec_command("file = open('/home/ubuntu/hosts', 'w')")
        #print b.readlines()
        ssh.exec_command("file.write('127.0.0.1 localhost\n')")
        for tag,ip in hosts_file_info.iteritems():
            ssh.exec_command("file.write('%s %s\n' % (ip,tag))")
        ssh.exec_command("file.close()")
        ssh.close()

public_dns = 'ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com'
print public_dns
hosts_file_info = {}
#hosts_file_info['1']='test'
#hosts_file_info['2']='test2'
#hosts_file_info['3']='test3'
#print hosts_file_info
update_hosts_file(public_dns,hosts_file_info)

2 个答案:

答案 0 :(得分:2)

您循环遍历public_dns变量中的每个字母。你可能想要这样的东西:

public_dns = ['ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com']

答案 1 :(得分:2)

您的第一个问题是public_dns是一个字符串,因此for dns in public_dns:将迭代该字符串的字符。您将使用'e',然后使用'c',然后使用'2'来尝试代码,依此类推。这不是一个无限循环,但它是一个长度为42的循环,我很容易看到你感到无聊并在完成之前取消它。

如果你只需要一台服务器,你仍然需要一个字符串列表,只是列表中只有一个字符串,如下所示:

public_dns = ['ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com']

你的下一个问题是你的ssh代码没有任何意义。您正在尝试执行Python语句,如file = open('/home/ubuntu/hosts', 'w'),就好像它们是bash命令一样。在bash中,该命令是语法错误,因为您不能在shell脚本中使用括号。如果您修复了这个问题,那只会调用file命令,该命令会抱怨无法找到名为=的文件。您可以将Python脚本上传到删除服务器然后运行它,通过<<HERE嵌入一个脚本,或者尝试编写交互式Python解释器脚本,但是您不能只在bash解释器中运行Python代码。

最重要的是,exec_command启动一个命令,并立即返回stdin / stdout / stderr通道。它不会等到命令完成。因此,您不能通过一个接一个地执行a,b,c = ssh.exec_command(…)来排序多个命令。


那么,你怎么能解决这个问题呢?重新开始比试图找出每个部分的目的以及如何使其发挥作用更有意义。

据我所知,在每台机器上,您正在尝试创建一个新文件,其内容仅基于您在本地的数据,并且在所有计算机上都相同。那么,为什么甚至尝试在创建该文件的每台远程计算机上运行代码?只需在本地创建一次,然后将其上传到每台远程计算机 - 例如,使用Paramiko的sftp。这样的事情(显然没有经过测试,因为我没有您的数据,服务器凭证等):

hosts = ['127.0.0.1 localhost\n']
for ip, tag in hosts_file_info.iteritems():
    hosts.append('%s %s\n' % (ip,tag))
for dns in public_dns:
    ssh = paramiko.SSHClient()
    # etc. up to connect
    sftp = paramiko.SFTPClient.from_transport(ssh.get_transport())
    f = sftp.open('/home/ubuntu/hosts', 'w')
    f.writelines(hosts)
    f.close()