我想从Python运行一个管道命令行linux / bash命令,它首先记录文件,然后拆分tar文件。命令在bash中看起来像这样:
> tar -cvf - path_to_archive/* | split -b 20m -d -a 5 - "archive.tar.split"
我知道我可以使用子进程执行它,通过设置shell = True,并将整个命令作为字符串提交,如下所示:
import subprocess
subprocess.call("tar -cvf - path_to_archive/* | split -b 20m -d -a 5 - 'archive.tar.split'", shell=True)
...但出于安全原因,我想找到一种方法来跳过“shell = True”部分,(它采用字符串列表而不是完整的命令行字符串,并且无法处理管道字符串正确)。在Python中有没有解决方案?即,是否有可能以某种方式设置链接管道,或其他一些解决方案?
答案 0 :(得分:24)
如果您想避免使用shell = True,可以手动使用subprocess pipes。
from subprocess import Popen, PIPE
p1 = Popen(["tar", "-cvf", "-", "path_to_archive"], stdout=PIPE)
p2 = Popen(["split", "-b", "20m", "-d", "-a", "5", "-", "'archive.tar.split'"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]
请注意,如果您不使用shell,则无法访问*等泛化字符的扩展。相反,您可以使用glob
模块。
答案 1 :(得分:3)
tar可以分裂:
tar -L 1000000 -F name-script.sh cf split.tar largefile1 largefile2 ...
#!/bin/bash
echo "${TAR_ARCHIVE/_part*.tar/}"_part"${TAR_VOLUME}".tar >&"${TAR_FD}"
tar -M -F name-script.sh cf split.tar
将它添加到你的python程序中。
答案 2 :(得分:2)
你有什么理由不能使用tarfile吗? | http://docs.python.org/library/tarfile.html
import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall()
tar.close()
使用tarfile编写类似于对象的文件而不是调用子进程。
答案 3 :(得分:1)
无耻的插件,我写了一个子进程包装器,以便在python中更容易地命令管道: https://github.com/houqp/shell.py
示例:
shell.ex("tar -cvf - path_to_archive") | "split -b 20m -d -a 5 - 'archive.tar.split'"