【问题标题】:subprocess.call and os.system return not found未找到 subprocess.call 和 os.system 返回
【发布时间】:2014-07-09 19:48:03
【问题描述】:

我正在尝试编写一个快速脚本,可用于检查过去 x 天内创建了哪些 AWS EC2 快照。

虽然我得到一个输出错误

/bin/sh: 1: /usr/local/bin/aws --profile dummydata0 ec2 describe-snapshots --owner-ids 000000000000 --filters Name=start-time,Values=2014-07-08*: not found

运行

/usr/local/bin/aws --profile dummydata0 ec2 describe-snapshots --owner-ids 000000000000 --filters Name=start-time,Values=2014-07-08*

在命令行上工作得很好,所以我猜我对 Linux 的基本理解在这里下降了。

这是我使用python ./script.py从命令行完整运行的脚本

#!/usr/bin/env python
import subprocess
import datetime

# Create your views here.

def main(numdays):
        base = datetime.date.today()
        date_list = [base - datetime.timedelta(days=x) for x in range(0, numdays)]
        environment = {'dummydata0':'000000000000', 'dummydata1':'111111111111', 'dummydata2':'222222222222'}
        data = []
        for date in date_list:
                date_string = str(date) + "*"
                # Python 3 prefers .values to .itervalues
                for key in environment:
                        call_snapshots = '"/usr/local/bin/aws --profile {0} ec2 describe-snapshots --owner-ids {1} --filters Name=start-time,Values={2}"'.format((key), (environment[key]), (date_string))
                        return subprocess.call(call_snapshots, shell=True)

main(7)

【问题讨论】:

标签: python linux amazon-web-services amazon-ec2 subprocess


【解决方案1】:

你的字符串中有一对引号:

call_snapshots = '"/usr/local/bin/aws --profile {0} ec2 describe-snapshots --owner-ids {1} --filters Name=start-time,Values={2}"'.format((key), (environment[key]), (date_string))

所以shell将收到的实际命令是:

"/usr/local/bin/aws --profile ... etc."

这些引号指​​示 shell 将整行视为单个项目。它不会查找名为 aws 的程序,而是查找名为 aws --profile .... 的程序,但这是行不通的。

您可以通过使用 pipes.quote 正确引用您的参数来解决此问题(在 Python 3 中重命名为 shlex.quote):

call_snapshots = '/usr/local/bin/aws --profile {0} ec2 describe-snapshots --owner-ids {1} --filters Name=start-time,Values={2}'.format(
    *map(pipes.quote, (key, environment[key], date_string)))
return subprocess.call(call_snapshots, shell=True)

或者,更好的是,避免使用 shell 并将参数作为列表传递:

call_snapshots = ['/usr/local/bin/aws',
  '--profile', key, 'ec2', 'describe-snapshots', '--owner-ids', environment[key],
  '--filters', 'Name=start-time,Values=' + date_string]
return subprocess.call(call_snapshots)

[AWS 没有针对这类事情的 Python API 吗?]

【讨论】:

  • 非常好,作为列表的参数是我的首选选项,并且效果很好。是的,它确实如此,并且它被称为 Boto,但是,我真的很努力地使用它,并且无法像 CLI 工具那样通过任何合理的努力让它工作。
猜你喜欢
  • 1970-01-01
  • 2015-05-20
  • 2019-07-29
  • 2019-03-23
  • 2013-01-17
  • 2013-09-15
  • 1970-01-01
  • 2021-11-06
  • 2011-09-07
相关资源
最近更新 更多