Команда ожидания всплывающего окна Python работает не так, как ожидалось

#python #powershell #popen

#python #powershell #всплывающее окно

Вопрос:

У меня есть сценарий PowerShell, который вызывает API и возвращает 0 или 99 в зависимости от того, прошел ли запрос POST. Мой код PowerShell:

 try
{
    Invoke-RestMethod -uri $url -Method Post -Body $body -ContentType 'application/json' -ErrorAction Stop

    return 0
}
catch
{
    return 99
}
 

Вот как я вызываю скрипт из своего скрипта Python:

 req =    subprocess.Popen([r'C:WINDOWSsystem32WindowsPowerShellv1.0powershell.exe',
                             '-ExecutionPolicy',
                             'Unrestricted',
                             './call.ps1',
                             param1, param2], cwd=os.getcwd())

    print("^^^^^^^")
    result = req.wait() #something is going wrong here
    print("****************")
    print(result)
  
    if result == 0:
        # do something
    else:
        # do something else
 

Теперь вот где все идет не так. Даже при сбое запроса POST переменная «результат» по-прежнему имеет значение «0», а не «99». Когда я отдельно запускаю сценарий PowerShell, я вижу, что он возвращает 99, когда запрос POST завершается неудачно. Похоже, проблема не в файле PowerShell.

При отладке файла Python это то, что я вижу на консоли: (обратите внимание на порядок операторов печати в коде Python)

 ^^^^^^^
99
****************
0
 

Одна вещь, которую я не понимаю, это то, что «99» делает на выходе? Я даже не печатаю результат между « ^^^^^ » и « ***** «. Итак, если сценарий PowerShell возвращает 99, почему он меняется на 0 после « ***** «?

Ответ №1:

Вывод 99 создается PowerShell, потому что вы использовали return вместо exit . Из-за этого скрипт выводит 99 и завершает работу с кодом выхода 0 (который req.wait() и получает). Кроме того, ваша командная строка PowerShell не создана таким образом, чтобы фактически возвращать правильный код выхода из скрипта, поэтому, даже если бы вы использовали exit вместо return процесса, он вернул бы только 0 в случае успеха или 1 в случае ошибки.

Чтобы PowerShell вернул код выхода скрипта, вам нужно либо вернуть код выхода самостоятельно

 powershell.exe -Command "amp;{.call.ps1; exit $LASTEXITCODE}"
 

или вызовите скрипт, используя -File параметр

 powershell.exe -File .call.ps1
 

Чтобы устранить проблему, измените свой код PowerShell на это:

 try {
    Invoke-RestMethod -uri $url -Method Post -Body $body -ContentType 'application/json' -ErrorAction Stop
    exit 0
} catch {
    exit 99
}
 

и ваш код Python для этого:

 req = subprocess.Popen([r'C:WINDOWSsystem32WindowsPowerShellv1.0powershell.exe',
      '-ExecutionPolicy', 'Unrestricted',
      '-File', './test.ps1',
      param1, param2], cwd=os.getcwd())

print("^^^^^^^")
result = req.wait()
print("****************")
print(result)
 

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

1. Большое вам спасибо за это подробное объяснение, Ансгар. Теперь мои файлы полностью работают так, как ожидалось. Честно говоря, я бы не смог разобраться в этом самостоятельно. Еще раз большое вам спасибо 🙂

Ответ №2:

req.wait() вернет код завершения программы, которую вы запустили. В этом случае power shell возвращает правильный код выхода 0. Кажется, он просто выводит «99», что вы и видите на выходе.

Возможно, вы захотите использовать:

 out = subprocess.check_output(...)
print out