python子进程模块不能用特殊字符解析文件名"("

时间:2015-04-02 19:38:59

标签: python bash subprocess special-characters file-not-found

我有一个Python程序,它读取文件然后将它们分成一定大小的tar球。

我的一个文件不仅包含空格,还包含括号。我有以下代码:

cmd = "/bin/tar -cvf " +  tmpname +  " '" + filename + "'"

注意:这些是在filename变量之外的双引号内的单引号。这有点难以看清。

其中tmpnamefilename是for循环中的变量,每次迭代都会发生变化(不相关)。

正如你所看到的文件名我在tarballing中包含文件名周围的单引号,以便shell(bash)按原样解释它,并且不会尝试进行变量替换,而#34;" "将做或将执行“将要执行的程序”。

据我所知,cmd变量包含shell根据我的意愿解释命令的确切语法。但是,当我运行以下子进程命令替换cmd变量时:

cmdobj = call(cmd, shell=True)

我得到以下输出/错误:

  

/ bin / tar:237-r Property Transport Request(PTR)012314.pdf:无法统计:没有此类文件或目录

     

/ bin / tar:由于先前的错误退出故障状态

     

无法停止:237-r物业运输申请(PTR)012314.pdf

我甚至在运行subprocess命令之前将命令输出到控制台,以查看在shell中运行时它的外观,它是:

cmd: /bin/tar -cvf tempname0.tar '237-r Property Transport Request (PTR) 012314.pdf'

当我在shell中运行上面的命令时,它工作得很好。不太确定这里发生了什么。求救!

2 个答案:

答案 0 :(得分:4)

如果从其他目录运行,则将list args shell=True完整路径传递给该文件:

from subprocess import check_call

check_call(["tar","-cvf",tmpname ,"Property Transport Request (PTR) 012314.pdf"])

同时使用tar而不是'bin/tar'。如果命令返回非零退出状态,check_call将引发CalledProcessError

答案 1 :(得分:2)

作为子进程模块一部分的call方法应该传递一个字符串数组。

在命令行上,您可以调用

tar -cvf "file folder with space/"

以下在python中是等效的

call(["tar", "-cvf", "file folder with space/"])

您正在shell中进行此调用

"tar -cvf 'file folder with space/'"

这导致shell查找一个名为`tar -cvf'文件夹的程序,其中包含空格/'

这可以避免字符串连接,从而使代码更清晰。