为什么在使用 * 通配符时通过 Python 的 subprocess.call 调用时 tar 无法创建存档?

Why does tar fail to create an archive when called via Python's subprocess.call while using a * wildcard?

我正在编写一个 python 脚本,它应该从现有文件中提取一些数据,然后将原始文件打包成几个 tar 球。文件名格式如下所示:

system_yymmddT0000.zip

其中 system 可以是多个名称之一,YYMMDDThhmm 是创建日期和时间。

为了完成这项工作,我使用 tar 到 Python 的 subprocess.call 因此,对于日期为 1704 的文件 star,例如 SAP_1704T0000.zip,命令为:

subprocess.call(["tar", "-cvf", "SAP_2017_04.tar", "SAP_1704*", "1>", "SAP_2017_04.filelist"])

然而,当我运行这个脚本时,我得到以下错误:

tar: SAP_1704*: Cannot stat: No such file or directory
tar: 1>: Cannot stat: No such file or directory
tar: SAP_2017_04.filelist: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

我也试过像这样将所有参数打包在一起:

subprocess.call(["tar", "-cvf SAP_2017_04.tar SAP_1704* 1> SAP_2017_04.filelist"])(参数之间没有逗号)。但是,然后我收到以下错误:

tar: Cowardly refusing to create an empty archive
Try `tar --help' or `tar --usage' for more information.

我不知道我做错了什么,因为在文件夹内手动导航和 运行 命令 tar cvf SAP_2017_04.tar SAP_1704* 1> SAP_2017_04.filelist 工作得很好。

没关系,自己想通了(至少我是这么认为的)。它是这样工作的:

substring = r"tar, -cvf SAP_2017_04.tar SAP_1704* 1> SAP_2017_04.filelist"
subprocess.call(substring, shell=True)

似乎有两个问题 - 转义一些特殊字符并尝试将参数列表传递给 subprocess.call,而在使用 shell=True 时应将其作为单个字符串传递。

非常感谢@CMMCD @BoarGules 和@ErHarshRathore 让我走上正轨!

tar 不处理通配符,它​​们需要由调用它的程序处理。 通常,那个程序是shell。

然而,它不一定是;通过在本机 Python 而不是使用 shell=True:

中完成工作,您可以获得更安全的操作(如果您的任何参数是用户可配置的)
subprocess.call(['tar', '-cvf', 'SAP_2017_04.tar'] + glob.glob('SAP_1704*'),
                stdout=open('SAP_2017_04.filelist', 'w'))
  • 而不是 1>somefile(对您的 shell 的指令 重定向标准输出,FD 1,写入 somefile),我们使用 stdout=open('somefile', 'w') 告诉 Python 同样的事情。
  • 不是直接将 SAP_1704* 直接放在命令行中,而是在 Python 中调用 glob.glob('SAP_1704*'),并将列表 returns 添加到参数列表中。