简体   繁体   English

使用子进程模块在Python中执行管道命令的任何方法,而不使用shell = True?

[英]Any way to execute a piped command in Python using subprocess module, without using shell=True?

I want to run a piped command line linux/bash command from Python, which first tars files, and then splits the tar file. 我想从Python运行一个管道命令行linux / bash命令,它首先记录文件,然后拆分tar文件。 The command would look like something this in bash: 命令在bash中看起来像这样:

> tar -cvf - path_to_archive/* | split -b 20m -d -a 5 - "archive.tar.split"

I know that I could execute it using subprocess, by settings shell=True, and submitting the whole command as a string, like so: 我知道我可以使用子进程执行它,通过设置shell = True,并将整个命令作为字符串提交,如下所示:

import subprocess    

subprocess.call("tar -cvf - path_to_archive/* | split -b 20m -d -a 5 - 'archive.tar.split'", shell=True)

...but for security reasons I would like to find a way to skip the "shell=True" part, (which takes a list of strings rather than a full command line string, and which can not handle the pipe char correctly). ...但出于安全原因,我想找到一种方法来跳过“shell = True”部分(它采用字符串列表而不是完整的命令行字符串,并且无法正确处理管道char)。 Is there any solution for this in Python? 在Python中有没有解决方案? Ie, is it possible to set up linked pipes somehow, or some other solution? 即,是否有可能以某种方式设置链接管道,或其他一些解决方案?

If you want to avoid using shell=True, you can manually use subprocess pipes . 如果要避免使用shell = True,可以手动使用子进程管道

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]

Note that if you do not use the shell, you will not have access to expansion of globbing characters like *. 请注意,如果不使用shell,则无法访问*等泛化字符的扩展。 Instead you can use the glob module. 相反,您可以使用glob模块。

tar can split itself: tar可以分裂:

tar -L 1000000 -F name-script.sh cf split.tar largefile1 largefile2 ...

name-script.sh name-script.sh

#!/bin/bash
echo "${TAR_ARCHIVE/_part*.tar/}"_part"${TAR_VOLUME}".tar >&"${TAR_FD}"

To re-assemble 要重新组装

tar -M -F name-script.sh cf split.tar

Add this to your python program. 将它添加到您的python程序中。

Is there any reason you can't use tarfile? 你有什么理由不能使用tarfile吗? | | http://docs.python.org/library/tarfile.html http://docs.python.org/library/tarfile.html

import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall()
tar.close()

Just write like a file like object using tarfile rather than invoking subprocess. 使用tarfile编写类似于对象的文件而不是调用子进程。

Shameless plug, I wrote a subprocess wrapper for easier command piping in python: https://github.com/houqp/shell.py 无耻的插件,我写了一个子进程包装器,以便在python中更容易命令管道: https//github.com/houqp/shell.py

Example: 例:

shell.ex("tar -cvf - path_to_archive") | "split -b 20m -d -a 5 - 'archive.tar.split'"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM