是否可以在传递给子进程的shell字符串中进行变量替换?

2024-10-04 03:28:39 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有这个:

>>> grepstring="mystring"
>>> p = subprocess.Popen("ls -l | grep grepstring", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

subprocess.Popen调用中,如何将grepstring替换为mystring?在


Tags: truestderrstdoutshelllsgrepsubprocesspopen
2条回答

如果可能的话,正确的做法是进行变量替换。事实上,首先不要使用外壳。您真正想要的是传递grep一个参数;您需要通过变量替换来完成此操作的唯一原因是您没有运行grep,而是在运行一个shell,并试图找出如何让它以您想要的方式运行grep。在

如果您只想实现shell ${grepstring}的等效功能,那么最好使用Python的字符串处理命令str.format,正如Martijn Pieters所建议的那样。但是如果grepstring中有一个空格,这就行不通了。或者特殊的外壳字符。或者,更糟的是,它可以工作,但不是您想要的方式(例如,如果grepstring是{})。在

您可以尝试编写代码进行清理,然后正确引用所有字符串,但这是一项愚蠢的任务。简单的解决方案是在最简单的情况下不使用shell(比如文本shell管道字符串)。subprocess文档有一整节内容是关于替换旧函数和shell函数的,其中包括Replacing shell pipeline。在

所以:

grepstring="mystring"
p0 = Popen(['ls', '-l'], stdout=PIPE)
p = Popen(['grep', grepstring], stdin=p0.stdout, stdout=PIPE, stderr=PIPE)
p0.stdout.close()

现在,您得到了一个p,它的作用与原始示例中的相同,只是grepstring只是Popen的普通参数,而不是一个必须引用、清理并填充到shell字符串中的字符串。在

如果你能很容易地使用Python库中的任何一个,那么就可以很容易地使用Python的库来实现这一点。在

使用字符串插值,如^{}

subprocess.Popen("ls -l | grep {}".format(grepstring), ...)

但是请注意warnings on the ^{} documentation在shell中执行不受信任的命令。在

相关问题 更多 >