有没有办法在Python中使用subprocess模块执行管道命令,而不使用shell=True?
我想在Python中运行一个Linux/bash的命令,这个命令首先会把文件打包成一个tar文件,然后再把这个tar文件分割开。这个命令在bash中大概是这样的:
> tar -cvf - path_to_archive/* | split -b 20m -d -a 5 - "archive.tar.split"
我知道我可以使用subprocess模块来执行这个命令,只需要把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中有没有什么解决方案?也就是说,有没有办法以某种方式设置连接的管道,或者其他的解决方案?
4 个回答
2
有没有什么原因让你不能使用tarfile? | http://docs.python.org/library/tarfile.html
import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall()
tar.close()
只需像使用文件一样使用tarfile,而不是调用子进程。
25
如果你想避免使用shell=True这个选项,可以手动使用subprocess管道。
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
这个模块来实现类似的功能。
3
tar可以自己分割:
tar -L 1000000 -F name-script.sh cf split.tar largefile1 largefile2 ...
name-script.sh
#!/bin/bash
echo "${TAR_ARCHIVE/_part*.tar/}"_part"${TAR_VOLUME}".tar >&"${TAR_FD}"
重新组合
tar -M -F name-script.sh cf split.tar
把这个加到你的Python程序里。