我试图在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,那么我会看到提到的错误
答案 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,从而消除了一种潜在的错误来源。