【问题标题】:ssh into aws server and edit hosts filessh 进入 aws 服务器并编辑 hosts 文件
【发布时间】:2014-01-11 07:53:27
【问题描述】:

我的代码:

由于某种原因,这似乎是无限循环并重复打印“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)

【问题讨论】:

  • 看起来您正在尝试执行 Python 语句,就好像它们是 bash 命令一样,例如 file = open('/home/ubuntu/hosts', 'w')。我不确定这是否会给你一个 bash 语法错误,或者来自file 的错误,比如cannot open '=' (No such file),但我相信它不会有任何用处。
  • 顺便说一句,请查看 Fabric docs.fabfile.org/en/1.8。它使很多这种类型的自动化变得简单方便。

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


【解决方案1】:

您的第一个问题是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()

【讨论】:

  • 谢谢伙计,不知道我可以这样使用 sftp
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2011-04-08
    • 2017-03-11
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 2014-08-04
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多