#python #powershell

Вопрос:

Здравствуйте, я пытаюсь написать скрипт для распаковки файлов bz2 с помощью 7zip и python.

Сначала, когда я пишу

 PS> amp; 'C:Program Files7-zip7z.exe' e D:pathexample.bz2
 

с powershell он работает отлично.

Поэтому я попробовал это с помощью Python:

 import glob
import subprocess

target = r"D:path*.bz2"
tab = glob.glob(target)

for i in range(len(tab)):
    subprocess.call("amp; 'C:\Program Files\7-zip\7z.exe' e %s" %tab[i], shell=True)
 

И я получил это сообщение об ошибке: amp; было неожиданным.
У кого-нибудь есть идея, почему ?

Я использую Python 3.9.2

Комментарии:

1. amp; является оператором вызова для PowerShell

2. Да, но если я правильно понял, функция вызова копирует то, что указано в кавычках в powershell, поэтому я обязан исправить это ?

3. amp; является специфичным для Powershell. Поскольку вы выполняете это на Python, вам не нужна командаamp;. Вы должны быть в состоянии просто опустить его. Похоже, вы ожидаете получить доступ к командам Powershell, но это не относится к Python.

Ответ №1:

Используя shell=True , вы решаете передать командную строку в собственную оболочку платформы, которая в Windows является cmd.exe , а не PowerShell, поэтому от вашей командной строки PowerShell принципиально нельзя ожидать, что она будет работать как есть.

Если мы сделаем шаг назад: вам вообще не нужно вовлекать оболочку в свой 7z.exe вызов, и это также ускоряет вашу работу.

Если опустить shell=True , целевой исполняемый файл и его аргументы должны быть переданы как элементы массива, а не как одна строка командной строки.

 for i in range(len(tab)):
  exitCode = subprocess.call([ 'C:\Program Files\7-zip\7z.exe', 'e', tab[i] ])
 

Обратите внимание на использование exitCode = , которое фиксирует 7z.exe код выхода и, следовательно, позволяет проверять наличие сбоя.

В качестве альтернативы вы можете позволить Python автоматически создавать исключение при сбое, используя subprocess.check_call() вместо subprocess.call()