Любой способ выполнить команду piped в Python с использованием модуля подпроцесса, не используя shell = True?
Я хочу запустить командную строку linux/ bash с помощью командной строки из Python, которая сначала записывает файлы, а затем разбивает файл 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" (которая берет список строк, а не полную строку командной строки и не может обрабатывать канал char правильно). Есть ли решение для этого в Python? I.e., возможно ли каким-либо образом установить связанные каналы или какое-то другое решение?
Ответы
Ответ 1
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.
Ответ 2
Если вы хотите избежать использования оболочки = 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]
Обратите внимание, что если вы не используете оболочку, у вас не будет доступа к расширению таких символов, как *. Вместо этого вы можете использовать модуль glob
.
Ответ 3
Есть ли причина, по которой вы не можете использовать tarfile? | http://docs.python.org/library/tarfile.html
import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall()
tar.close()
Просто напишите как файл, похожий на объект, используя tarfile, а не вызывайте подпроцесс.
Ответ 4
Бесстыдный плагин, я написал оболочку подпроцесса для упрощения командной строки в python:
https://github.com/houqp/shell.py
Пример:
shell.ex("tar -cvf - path_to_archive") | "split -b 20m -d -a 5 - 'archive.tar.split'"