我想从我的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)
请建议如何做到这一点。
答案 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)