Python 子进程模块无法解析带有特殊字符的文件名"("



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

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

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

注意:这些是文件名变量外的双引号中的单引号。这有点难看。

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

正如你所看到的,我正在tarballing的文件名在文件名周围包含单引号,这样shell(bash)就可以按原样解释它,而不会试图进行变量替换"将要执行的程序或"将要执行"的程序。

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

cmdobj = call(cmd, shell=True)

我得到以下输出/错误:

/bin/tar:237-r属性传输请求(PTR)012314.pdf:无法统计:没有这样的文件或目录

/bin/tar:由于以前的错误而以失败状态退出

无法标记:237-r财产运输请求(PTR)012314.pdf

我甚至在运行子流程命令之前将命令打印到控制台,看看它在shell中运行时会是什么样子,它是:

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

当我在shell中按原样运行上述命令时,它运行得很好。不太确定这里发生了什么。救命!

如果从不同目录运行,则将不带shell=Trueargslist完整路径传递到文件:

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

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

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

在命令行上,您可以调用

tar -cvf "file folder with space/"

以下内容在python 中等效

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

您正在外壳中进行此呼叫

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

这导致shell查找一个程序,该程序的确切名称为"tar-cvf"文件夹,其中包含空格/""

这样可以避免字符串串联,从而使代码更加简洁。

最新更新