假设我有这个:
>>> grepstring="mystring"
>>> p = subprocess.Popen("ls -l | grep grepstring", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
我如何在通话中替换grepstring
为?mystring
subprocess.Popen
假设我有这个:
>>> grepstring="mystring"
>>> p = subprocess.Popen("ls -l | grep grepstring", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
我如何在通话中替换grepstring
为?mystring
subprocess.Popen
使用字符串插值,例如str.format()
:
subprocess.Popen("ls -l | grep {}".format(grepstring), ...)
但是请注意文档中有关在 shell 中执行不受信任的命令的警告。subprocess
如果可能的话,正确的做法是不要进行变量替换。而且,事实上,首先不要使用外壳。你真正想要的是传递grep
一个论点;你需要通过变量替换来做到这一点的唯一原因是你没有运行grep
,你正在运行一个 shell 并试图弄清楚如何让它以grep
你想要的方式为你运行。
如果你只想做一个 shell 的等价物${grepstring}
,你可以用 Python 的字符串处理命令来做 - 理想情况下str.format
,正如 Martijn Pieters 所建议的那样。grepstring
但是,如果其中有空间,这将不起作用。或特殊的外壳字符。或者,更糟糕的是,它会工作,但不是你想要的方式(例如,如果grepstring
是$(rm -rf /)
.
您可以尝试编写代码来清理所有字符串,然后正确引用,但这是愚蠢的差事。简单的解决方案是除了最简单的情况(如文字 shell 管道字符串)之外,不使用 shell。文档有一整subprocess
节关于替换旧函数和 shell 函数,其中包括替换 shell 管道。
所以:
grepstring="mystring"
p0 = Popen(['ls', '-l'], stdout=PIPE)
p = Popen(['grep', grepstring], stdin=p0.stdout, stdout=PIPE, stderr=PIPE)
p0.stdout.close()
现在,您的 ap
与原始示例中的行为相同,除了它grepstring
只是 的普通参数Popen
,而不是您必须引用和清理并填充到 shell 字符串中的字符串。
如果你做了很多这样的事情,你可以很容易地把它包起来,或者使用 PyPI 上为你做的任何 69105 库(范围从保持简单的库到使用巧妙技巧的库) Python 管道看起来像 bash)。