字符串格式化后找不到os.system命令

时间:2019-08-08 12:29:16

标签: python python-2.7

我试图在os.system命令中传递一个变量,但是在字符串格式标记之后我收到一条错误消息“找不到命令”。似乎它尝试在将字符串格式化为命令之后立即执行文本。

import os

BOOT_VOLUME_ATTACHMENT_ID = os.popen("terraform output | grep volume_attachment_id | cut -d ' ' -f 3").read()

os.system('oci compute boot-volume-attachment detach --force  --wait-for-state DETACHED --boot-volume-attachment-id {0} --region region1' .format(BOOT_VOLUME_ATTACHMENT_ID))

结果是以下错误:

sh: line 1: --region: command not found

为什么Python在将字符串格式化为命令后立即尝试执行字符串?

我正在使用Python2.7

更新

问题似乎出在变量BOOT_VOLUME_ATTACHMENT_ID中。如果我将此变量更改为手动字符串,请说“ 123”,它可以正常工作。但是,如果我使用os.popen,那么我会看到提到的错误

1 个答案:

答案 0 :(得分:2)

除了os.system不如subprocess之外,可能的问题是.format()完成的替换过程。

您应该尝试使用

代替代码
BOOT_VOLUME_ATTACHMENT_ID = "123"
print(repr('oci compute boot-volume-attachment detach --force  --wait-for-state DETACHED --boot-volume-attachment-id {0} --region region1'.format(BOOT_VOLUME_ATTACHMENT_ID)))

看看它输出什么。

这将告诉您--region之前是否有奇怪的东西(例如换行符)。

问题更新后,很明显您的BOOT_VOLUME_ATTACHMENT_ID不是您声称的那样。相反,它包含另一个程序的输出,该程序在大多数情况下会在末尾添加换行符。

如果您以这种方式获取内容并将其插入字符串中,则此换行符将被转移到目标字符串中,告诉shell执行两个命令。

解决方案是在.strip()调用之后立即使用os.popen()


关于子流程:

如果这样做,您的程序将变得更干净(例如,更少的注射倾向)

import subprocess
BOOT_VOLUME_ATTACHMENT_ID = "123"
subprocess.call(['oci', 'compute', 'boot-volume-attachment', 'detach', '--force', '--wait-for-state', 'DETACHED', '--boot-volume-attachment-id', BOOT_VOLUME_ATTACHMENT_ID, '--region', 'region1'])

原因是这样可以避免在程序和oci之间使用shell,从而消除了一种潜在的错误来源。