Я пытаюсь скопировать некоторые файлы по следующей схеме:
/var/lib/cassandra/data/*/*/snapshots/<snapid>/
Если я выполняю команду tar вручную, она работает без проблем, но когда я выполняю ее с помощью python, она не работает.
Я выполняю это следующим образом:
output = subprocess.check_output(["tar","cf", outputfile, snappath])
Но пока я получаю следующую ошибку, я могу сменить файл вручную
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, но кажется, что регулярное выражение *
не работает
3 ответа
Когда вы запускаете эту команду в приглашении оболочки, оболочка расширяет подстановочные знаки. Если вы хотите, чтобы Python использовал расширение по шаблону, вы должны запросить его отдельно.
Из вашего вопроса не ясно, какая часть не работает, но я думаю, вы хотите
cmd = ['tar', 'cf', outputfile]
cmd.extend(glob.glob(snappath))
output = subprocess.check_output(cmd)
Добавление shell=True
решило бы вашу проблему, если бы вы не использовали список аргументов для subprocess
; тогда оболочка проанализировала бы строку и выполнила бы подстановочный знак. Но когда вы предоставляете список, shell=True
ничего не делает, потому что вы (как предполагается) уже выполнили анализ командной строки, который будет выполнять оболочка. Но, как правило, если ваши потребности просты, вы все равно должны избегать shell=True
, так как сама оболочка создает ряд сложностей, о которых вам необходимо знать.
Вместо этого я предлагаю использовать библиотеку 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
, чтобы существовала оболочка для расширения этих переменных.
Однако, чтобы использовать оболочку, вы должны дать функциям подпроцесса строку, а не список:
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. орг / 2 / библиотека / tarfile.html
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.