[英]Why does tar fail to create an archive when called via Python's subprocess.call while using a * wildcard?
I'm writing a python script that should extract some data from within the existing files and then pack the original files into several tarballs.我正在编写一个 python 脚本,它应该从现有文件中提取一些数据,然后将原始文件打包成几个 tarball。 The filename format looks like this:文件名格式如下所示:
system_yymmddT0000.zip
where system
can be one of several names and YYMMDDThhmm
is a date and time of creation.其中system
可以是多个名称之一, YYMMDDThhmm
是创建日期和时间。
To make this work, I'm using tar through Python's subprocess.call
so, for files starting with date 1704 like SAP_1704T0000.zip
, the command is:为了使这项工作,我使用焦油通过Python的subprocess.call
所以,对于开始日期1704文件一样SAP_1704T0000.zip
,命令是:
subprocess.call(["tar", "-cvf", "SAP_2017_04.tar", "SAP_1704*", "1>", "SAP_2017_04.filelist"])
However, when I run this script, I get the following error:但是,当我运行此脚本时,出现以下错误:
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
I also tried to pack all the arguments together like this:我还尝试将所有参数打包在一起,如下所示:
subprocess.call(["tar", "-cvf SAP_2017_04.tar SAP_1704* 1> SAP_2017_04.filelist"])
(no commas between arguments). subprocess.call(["tar", "-cvf SAP_2017_04.tar SAP_1704* 1> SAP_2017_04.filelist"])
(参数之间没有逗号)。 However, then I got the following error:但是,然后我收到以下错误:
tar: Cowardly refusing to create an empty archive
Try `tar --help' or `tar --usage' for more information.
I can't figure out what I'm doing wrong, since manually navigating inside the folder and running the command tar cvf SAP_2017_04.tar SAP_1704* 1> SAP_2017_04.filelist
works just fine.我不知道我做错了什么,因为在文件夹内手动导航并运行命令tar cvf SAP_2017_04.tar SAP_1704* 1> SAP_2017_04.filelist
工作得很好。
Wildcards aren't processed by tar
, they need to be processed by the program that calls it.通配符不由tar
处理,它们需要由调用它的程序处理。 Usually , that program is a shell.通常,该程序是一个外壳程序。
However, it doesn't have to be;然而,它不一定是; you can get much safer operation (if any of your parameters are user-configurable) by doing the work in native Python instead of using shell=True
:通过在本机 Python 中完成工作而不是使用shell=True
,您可以获得更安全的操作(如果您的任何参数是用户可配置的):
subprocess.call(['tar', '-cvf', 'SAP_2017_04.tar'] + glob.glob('SAP_1704*'),
stdout=open('SAP_2017_04.filelist', 'w'))
1>somefile
(an instruction to your shell to redirect stdout, FD 1, to write to somefile
), we use stdout=open('somefile', 'w')
to tell Python the same thing.取而代之的1>somefile
(你的shell中的重定向标准输出,FD 1,指令写入somefile
),我们使用stdout=open('somefile', 'w')
来告诉Python同样的事情。SAP_1704*
directly in the command line, we call glob.glob('SAP_1704*')
in Python, and add the list it returns to the argument list.我们不是直接将SAP_1704*
放在命令行中,而是在 Python 中调用glob.glob('SAP_1704*')
,并将它返回的列表添加到参数列表中。Never mind, figured it out myself (at least I think so).没关系,自己想出来的(至少我是这么认为的)。 It works like this:它是这样工作的:
substring = r"tar, -cvf SAP_2017_04.tar SAP_1704* 1> SAP_2017_04.filelist"
subprocess.call(substring, shell=True)
It seems there were two problems - escaping some special characters and also attempting to pass a list of arguments to the subprocess.call
while it should be passed as a single string when using shell=True
.似乎有两个问题 - 转义一些特殊字符并尝试将参数列表传递给subprocess.call
而在使用shell=True
时它应该作为单个字符串传递。
Big thanks to @CMMCD @BoarGules and @ErHarshRathore for putting me on the right track!非常感谢@CMMCD @BoarGules 和@ErHarshRathore 让我走上正轨!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.