Python 2.6:包含python变量的管道bash命令(在python脚本中)

时间:2016-06-14 11:57:47

标签: python linux bash subprocess python-2.6

我想从我的python脚本运行以下bash命令:

stat --printf='%U%G%a' /tmp/file1.csv &&md5sum /tmp/file1.csv |awk '{print $1}'

我是使用subprocess.Popen完成的,如下所示:

Command=subprocess.Popen(["stat --printf='%U%G%a' file1.csv &&md5sum file1.csv|awk '{print $1}'"],stdout=subprocess.PIPE,shell=True)

但是我不需要对文件名进行硬编码,而是需要传递一个python变量。我试过了

filevar="/tmp/file.csv"
Command=subprocess.Popen(["stat --printf='%U%G%a' filevar &&md5sum filevar|awk '{print $1}'"],stdout=subprocess.PIPE,shell=True)

但上面的代码无效。

我已经完成了与How to pass a python variable to subprocess

相关的所有答案

到目前为止,我得到的最佳答案是piping python variable value to bash script (inside python script)

基于此,我尝试了:

Command=subprocess.Popen(["stat","--printf='%U%G%a'",filevar],stdout=subprocess.PIPE)

哪个效果很好。但是当我尝试包含更多像md5sum这样的命令时,它会抛出错误。

Command=subprocess.Popen(["stat","--printf='%U%G%a'",filevar,"&&","md5sum",filevar],stdout=subprocess.PIPE)

请建议如何做到这一点。

2 个答案:

答案 0 :(得分:1)

要支持空格和其他shell元字符,请使用Putty: login, execute command/change environment variable, and do NOT close the session

#!/usr/bin/env python
import pipes
from subprocess import check_output

path = "/path/to/file.csv"
output = check_output("stat --printf='%U%G%a' {path} && md5sum {path}"
                      .format(path=pipes.quote(path))
                      + "|awk '{print $1}'", shell=True)

要获得Python 2.6上的check_output(),请参阅pipes.quote()

注意:pipes.quote()不是防弹的。不要将path传递给shell,除非它来自受信任的来源,否则您将面临执行任意shell命令的风险(What's a good equivalent to python's subprocess.check_call that returns the contents of stdout?)。

作为替代方案,您可以shell injection

#!/usr/bin/env python
from plumbum.cmd import stat, md5sum, awk  # $ pip install plumbum

path = "/path/to/file.csv"
stat["--printf=%U%G%a", path]()
output = (md5sum[path] | awk['{print $1}'])()

请参阅use plumbum to emulate the pipeline

根据您的情况,在没有外部命令的情况下在纯Python中实现命令可能是有意义的。

答案 1 :(得分:0)

当您致电Popen时,您只需将字符串传递给该函数即可。因此,您可以使用字符串格式将正确的变量放在那里:

filevar="/tmp/file.csv"
Command=subprocess.Popen(["stat --printf='%U%G%a' %(filevar) &&md5sum filevar|awk '{print $1}'" % {"filevar": filevar}],stdout=subprocess.PIPE,shell=True)