文件名包含与号的Python子进程调用

2024-09-30 01:29:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道S/O上已经有很多了,但我不知所措。这是重现问题的最小源集:

文件测试.py

from subprocess import call

Filename1     = "A & B.txt"
Filename2     = "A&B.txt"
Archivename1  = "A & B.7z"
Archivename2  = "A&B.7z"

ShellArgs     = ["7zip.bat", "a", Archivename1, Filename1]
call (ShellArgs, shell = False)

ShellArgs     = ["7zip.bat", "a", Archivename2, Filename2]
call (ShellArgs, shell = False)

文件7拉链蝙蝠

^{pr2}$

A&B.txt和{}可以是任何现有文件。如果您要尝试重现这个问题,我建议您使用空文件夹,因为这种错误行为会导致7-Zip尝试创建整个文件夹内容的存档。在

我遇到的问题是第一个调用有效,第二个调用不起作用,我相信原因是Python发现参数A & B.txt包含空格,因此它对参数进行了双引号引用。第二个失败,因为A&B.txt不包含空格,所以它不提供引号。因此,Windows可以看到命令行

"C:\Program Files\7-Zip\7z.exe" a A&B.7z A&B.txt

它将其解释为3个连锁命令-即

"C:\Program Files\7-Zip\7z.exe" a A
B.7z A
B.txt

不幸的是,第一个文件被7Zip解释为“命名归档文件A.7z,并将所有你能找到的东西都放在里面”(我让它运行了一夜,然后开始工作,在程序遍历的一个文件夹中找到一个35GB的文件)。在

当文件名没有空格时,如何避免引用参数失败?我自己也试过添加它们,但它们(我不确定“它们”是谁)很有帮助地避开了双引号-即将"变成了{}。我想其他特殊字符也可能引起类似的问题-我没有试过。在


Tags: 文件txt文件夹false参数zipshellcall
1条回答
网友
1楼 · 发布于 2024-09-30 01:29:12

为了避免Python的Windows subprocess模块中的错误,我认为subprocess.call工作正常。证明:

$ cat ./argtester.c
#include <stdio.h>

int main ( int argc, char** argv ) {
    int i = 0;

    while ( i < argc ) {
        printf("ARG %d: %s\n", i+1, argv[i]);
        ++i;
    }

    return 0;
}

所以,它会说出传递给它的每个参数,每行一个。希望我们不要给它传递任何嵌入换行符的参数。。。(我们没有)。在

^{pr2}$

还有你的程序,但是把7zip.exe改成{}。现在,编译argtester:

$ gcc -o argtester argtester.c

看看会发生什么:

$ python2.7 test.py
ARG 1: ./argtester
ARG 2: a
ARG 3: A & B.7z
ARG 4: A & B.txt
ARG 1: ./argtester
ARG 2: a
ARG 3: A&B.7z
ARG 4: A&B.txt

这正是我所期望的,考虑到这些论点。所以,我的预感是错误是与7z.exe或是{}。根据“我的代码是最有可能的罪魁祸首”的原则,我猜7zip.bat

"C:\Program Files\7-Zip\7z.exe" %*

这看起来非常可疑。翻译有很多方法。在Bash land做类似的事情,我会做:

/path/to/my/7z "$@"

"$@"扩展到所有参数,并且在将其传递给7z之前,还必须引用每个参数。如果我确实使用$@(注意缺少引号),那么我在*nix land中的错误将与您在MS land中的错误相同。在

看看批处理语法吧?或者完全避开批处理文件并给出7zip.exe的完整路径?在

相关问题 更多 >

    热门问题