【问题标题】:Automating EC2 creation using Python使用 Python 自动创建 EC2
【发布时间】:2015-05-29 08:08:39
【问题描述】:

我正在尝试使用 Python 脚本和 Windows 任务计划程序在 EC2 上自动创建 Windows 映像。到目前为止,我将此作为我的工作基线代码。

awsstring1 = 'aws ec2 create-image --instance-id i-49a0a7b3 --name "Node.Js.ServerTest " --output text  --description "Node.Js.ServerTest" --no-reboot'
subprocess.call(awsstring1)

现在我想在描述和名称中附加日期和时间作为附加信息。见下文

datestring = time.strftime("%c")
awsstring1 = 'aws ec2 create-image --instance-id i-49a0a7b3 --name "Node.Js.ServerTest %s" --output text  --description "Node.Js.ServerTest %s" --no-reboot' %(datestring, datestring))
subprocess.call(awsstring1)

现在代码运行没有错误,但它没有创建图像。是因为我创建awsstring1 的方式吗?如果是这样,是否有解决方法?

另外,有没有办法在运行subprocess.call 命令后获得输出?例如,我想捕获

的输出
subprocess.call('ls -a')

编辑: 当运行下面的代码时,它应该有一个创建图像的输出。

 awsstring1 = 'aws ec2 create-image --instance-id i-9bedb4b4 --name "rwong_TestInstance" --output text  --description "rwong_TestInstance" --no-reboot' 
 subprocess.call(awsstring1)

输出:

 {
   "ImageId": "ami-5731123e"
 }

我需要那个 ami-5731123e 部分。如果有办法将其发送到文本文件,那就太好了。当我需要运行类似的命令来获取 IP 地址时,获取输出也会对我有所帮助。

Edit2:我已编写此代码用于将输出保存到文本文件,但我收到“返回非零退出状态 255”的错误 此不带开头 ' 和 end ' 的命令将在命令行上运行。是否有关于如何格式化这样的字符串以使用 subprocess.check_call 执行的指南?

test = 'aws ec2 create-image --instance-id i-563b6379 --name "rwong_TestInstance" --output text  --description "rwong_TestInstance" --no-reboot'
test2 = r' > "V:\rwong\Work Files\Python\test.txt"' 
subprocess.check_call(test + test2)

【问题讨论】:

  • 您提到您正在通过“Windows 任务计划程序”执行此操作,但随后给出了运行ls -a 的示例,这不是 Windows 命令。你是在windows平台上做的吗?
  • 抱歉这个不好的例子。我更改了上面的帖子以反映我运行 subprocess.call 的目标。
  • 如果不使用不安全的shell=True,您绝对不能进行文件重定向。
  • 所以无论我走到哪里,它看起来都像死路一条?
  • 如果你使用check_output,就像我在下面的回答中提到的那样,你可以将输出捕获到一个字符串,然后使用python使用标准io函数将它写入一个文件。

标签: windows python-2.7 amazon-web-services amazon-ec2 subprocess


【解决方案1】:

如果您阅读docs for subprocess.call,您会发现您必须将多个参数作为list 传递,而不是作为字符串传递给subprocess.call

这意味着您应该改为执行以下操作:

awsstring1 = 'aws ec2 create-image --instance-id i-49a0a7b3 --name "Node.Js.ServerTest" --output text --description "Node.Js.ServerTest" --no-reboot'
subprocess.call(awsstring1.split())

请注意,这假设您希望通过空格分割参数,这是默认情况下 shell 的工作方式。或者,您可以通过将shell=True 作为关键字参数传递来强制subprocess.call 使用shell。默认值为False。但是,这是不安全的,因为它会使您面临 shell 注入攻击。

此外,要在不使用 shell 的情况下使事情正常工作,您可能需要删除内部双引号,除非您希望将它们逐字传递给 aws 命令,我对此表示怀疑。

此外,我会使用subprocess.check_call 而不是subprocess.call 来验证命令是否成功运行并且没有报告错误代码。

一般来说,要调试这些类型的问题,您应该在执行之前立即print 完整的命令。然后尝试在命令行上手动执行它。如果手动执行它不起作用,则需要修复该命令。如果手动执行它确实有效,那么它可能与用户或环境有关。确保您在这两种情况下都以相同的用户身份运行。您还可以使用env 命令打印出您当前的环境变量。然后使用diff 进行比较。另一种可能性是提示符下的 shell 转义之间的差异,这就是我前面提到双引号的原因。

最后,回答你关于捕获输出的问题:subprocess.check_output 会做你想做的事。

【讨论】:

  • 好的,我会用 subprocess.check_call 试试。如果仍然不起作用,那也没什么大不了的。我还编辑了我的帖子以在下面回答您的问题。
  • @RobertWong:在 Windows 上,您可以将命令作为字符串传递(它是本机接口)。 .split() 在这里不正确(如果其中有空格,它会拆分单引号参数)。在 Unix 上,shlex.split(awstring) 可能会显示列表的外观(尽管有一些极端情况——您应该自己调整列表)。
猜你喜欢
  • 2013-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
相关资源
最近更新 更多