Python tar 使用 shell 无效
Python tar using shell not working
我正在尝试 tar 一些具有以下模式的文件:
/var/lib/cassandra/data/*/*/snapshots/<snapid>/
如果我手动执行 tar 命令,它可以正常工作,但是当我使用 python 执行它时,它会失败。
我执行如下:
output = subprocess.check_output(["tar","cf", outputfile, snappath])
但是当我收到以下错误时,我可以 tar 手动文件
tar: /var/lib/cassandra/data/*/*/snapshots/20151215104608: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
Traceback (most recent call last):
File "./cassandrabackup2s3.py", line 68, in <module>
create_snapshot_file(snapid)
File "./cassandrabackup2s3.py", line 46, in create_snapshot_file
output = subprocess.check_output(["tar","cf", outputfile, snappath])
File "/usr/lib64/python2.7/subprocess.py", line 575, in check_output
raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['tar', 'cf', '/tmp/20151215104608.tgz', '/var/lib/cassandra/data/*/*/snapshots/20151215104608/']' returned non-zero exit status 2
我看到一些关于从 -cvzf
中删除“-
”或使用 shell=True 的帖子,但没有任何效果。这是使用 Shell=True
的输出
output = subprocess.check_output(["tar","cf", outputfile, snappath], shell=True)
tar 的语法似乎不正确:
tar: You must specify one of the `-Acdtrux' or `--test-label' options
Try `tar --help' or `tar --usage' for more information.
Traceback (most recent call last):
File "./cassandrabackup2s3.py", line 68, in <module>
create_snapshot_file(snapid)
File "./cassandrabackup2s3.py", line 46, in create_snapshot_file
output = subprocess.check_output(["tar","cf", outputfile, snappath], shell=True)
File "/usr/lib64/python2.7/subprocess.py", line 575, in check_output
raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['tar', 'cf', '/tmp/20151215103816.tgz', '/var/lib/cassandra/data/*/*/snapshots/20151215103816/']' returned non-zero exit status 2
我试过使用 tar 库,但 *
之类的正则表达式似乎不起作用
我建议改用 tarfile 库:https://docs.python.org/2/library/tarfile.html
编辑给你举个例子:
import glob
import tarfile
snaps = glob.glob("/var/lib/cassandra/data/*/*/snapshots/<snapid>/")
with tarfile.open("tared.tar","w") as tar:
for snap in snaps:
tar.add(snap)
当你在命令行上运行tar
,那么路径:
/var/lib/cassandra/data/*/*/snapshots/<snapid>/
由 shell 扩展,而不是由 tar
命令扩展。 check_output
不会进行 *
扩展,所以你需要 shell=True
是对的,这样 shell 就可以扩展这些变量。
但是,要使用 shell,您应该给子进程函数一个字符串,而不是一个列表:
output = subprocess.check_output("echo my command is here", shell=True)
所以你的 tar 命令,为了清楚起见,移到了单独的两行:
command = "tar cf {} {}".format(outputfile, snappath)
output = subprocess.check_output(command, shell=True)
正如@radek所说,您还可以使用tar模块:https://docs.python.org/2/library/tarfile.html
当您在 shell 提示符下 运行 此命令时,shell 会扩展通配符。如果要Python做通配符扩展,需要单独索取
从你的问题中不清楚哪个部分不起作用,但我想你想要
cmd = ['tar', 'cf', outputfile]
cmd.extend(glob.glob(snappath))
output = subprocess.check_output(cmd)
如果您没有使用 subprocess
的参数列表,添加 shell=True
会解决您的问题;那么 shell 将解析字符串并执行通配符扩展。但是当您提供一个列表时,shell=True
什么都不做,因为您(假设)已经执行了 shell 将执行的命令行解析。但一般来说,如果您的需求很简单,您应该避免使用 shell=True
,因为 shell 本身会带来一些您需要注意的复杂情况。
我正在尝试 tar 一些具有以下模式的文件:
/var/lib/cassandra/data/*/*/snapshots/<snapid>/
如果我手动执行 tar 命令,它可以正常工作,但是当我使用 python 执行它时,它会失败。
我执行如下:
output = subprocess.check_output(["tar","cf", outputfile, snappath])
但是当我收到以下错误时,我可以 tar 手动文件
tar: /var/lib/cassandra/data/*/*/snapshots/20151215104608: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
Traceback (most recent call last):
File "./cassandrabackup2s3.py", line 68, in <module>
create_snapshot_file(snapid)
File "./cassandrabackup2s3.py", line 46, in create_snapshot_file
output = subprocess.check_output(["tar","cf", outputfile, snappath])
File "/usr/lib64/python2.7/subprocess.py", line 575, in check_output
raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['tar', 'cf', '/tmp/20151215104608.tgz', '/var/lib/cassandra/data/*/*/snapshots/20151215104608/']' returned non-zero exit status 2
我看到一些关于从 -cvzf
中删除“-
”或使用 shell=True 的帖子,但没有任何效果。这是使用 Shell=True
output = subprocess.check_output(["tar","cf", outputfile, snappath], shell=True)
tar 的语法似乎不正确:
tar: You must specify one of the `-Acdtrux' or `--test-label' options
Try `tar --help' or `tar --usage' for more information.
Traceback (most recent call last):
File "./cassandrabackup2s3.py", line 68, in <module>
create_snapshot_file(snapid)
File "./cassandrabackup2s3.py", line 46, in create_snapshot_file
output = subprocess.check_output(["tar","cf", outputfile, snappath], shell=True)
File "/usr/lib64/python2.7/subprocess.py", line 575, in check_output
raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['tar', 'cf', '/tmp/20151215103816.tgz', '/var/lib/cassandra/data/*/*/snapshots/20151215103816/']' returned non-zero exit status 2
我试过使用 tar 库,但 *
之类的正则表达式似乎不起作用
我建议改用 tarfile 库:https://docs.python.org/2/library/tarfile.html
编辑给你举个例子:
import glob
import tarfile
snaps = glob.glob("/var/lib/cassandra/data/*/*/snapshots/<snapid>/")
with tarfile.open("tared.tar","w") as tar:
for snap in snaps:
tar.add(snap)
当你在命令行上运行tar
,那么路径:
/var/lib/cassandra/data/*/*/snapshots/<snapid>/
由 shell 扩展,而不是由 tar
命令扩展。 check_output
不会进行 *
扩展,所以你需要 shell=True
是对的,这样 shell 就可以扩展这些变量。
但是,要使用 shell,您应该给子进程函数一个字符串,而不是一个列表:
output = subprocess.check_output("echo my command is here", shell=True)
所以你的 tar 命令,为了清楚起见,移到了单独的两行:
command = "tar cf {} {}".format(outputfile, snappath)
output = subprocess.check_output(command, shell=True)
正如@radek所说,您还可以使用tar模块:https://docs.python.org/2/library/tarfile.html
当您在 shell 提示符下 运行 此命令时,shell 会扩展通配符。如果要Python做通配符扩展,需要单独索取
从你的问题中不清楚哪个部分不起作用,但我想你想要
cmd = ['tar', 'cf', outputfile]
cmd.extend(glob.glob(snappath))
output = subprocess.check_output(cmd)
如果您没有使用 subprocess
的参数列表,添加 shell=True
会解决您的问题;那么 shell 将解析字符串并执行通配符扩展。但是当您提供一个列表时,shell=True
什么都不做,因为您(假设)已经执行了 shell 将执行的命令行解析。但一般来说,如果您的需求很简单,您应该避免使用 shell=True
,因为 shell 本身会带来一些您需要注意的复杂情况。