Chr*_*ers 2 python bash shell quotes subprocess
我知道以前曾问过类似的问题,但它们似乎都是通过重新设计参数的传递方式(即使用列表等)来解决的。
但是,我这里有一个问题,因为我没有这个选项。有一个特定的命令行程序(我使用的是 Bash shell),我必须向其传递带引号的字符串。它不能不被引用,也不能有重复的参数,它只能是单引号或双引号。
command -flag 'foo foo1'
Run Code Online (Sandbox Code Playgroud)
我不会用command -flag foo foo1,也不会用command -flag foo -flag foo1。我认为这是命令接收输入方式的疏忽,但我无法控制它。
我传递参数如下:
self.commands = [
self.path,
'-flag1', quoted_argument,
'-flag2', 'test',
...etc...
]
process = subprocess.Popen(self.commands, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
results = process.communicate(input)
Run Code Online (Sandbox Code Playgroud)
哪里quoted_argument有像“foo foo1 foo2”这样的东西。我尝试转义单引号 ( "\'foo foo1 foo2\'"),但没有得到任何输出。
我知道这被认为是不好的做法,因为它解释起来不明确,但我没有其他选择。有任何想法吗?
shell 将命令字符串分解为列表。引号告诉 shell 将多个单词放入单个列表项中。由于您是自己构建列表,因此您可以将单词添加为单个项目(不带引号)。
这两个Popen命令是等价的
Popen("command -flag 'foo foo1'", shell=True)
Popen(["command", "-flag", "foo foo1"])
Run Code Online (Sandbox Code Playgroud)
编辑
这个答案涉及 shell 中的转义字符。如果您不使用 shell,则无需添加任何引号或转义符,只需放入字符串本身。跳过 shell 还存在其他问题,例如管道命令、运行后台作业、使用 shell 变量等。这些都可以在 python 而不是 shell 中完成。