Эта та же самая проблема мучила меня в течение недели. Мне пришлось безопасно вводить пароль из пользовательского ввода через подпроцесс, потому что я пытался избежать введения уязвимости внедрения команд. Вот как я решил проблему с небольшой помощью коллеги.
import subprocess
command = ['command', 'option1', '--password']
subprocess.Popen(command, stdin=subprocess.PIPE).wait(timeout=60)
.wait (timeout = int) был самым важным компонентом, поскольку он позволяет пользователю передавать ввод в stdin. В противном случае тайм-аут по умолчанию равен 0 и не оставляет пользователю времени для ввода данных, что приводит к появлению строки None или null. Взял меня навсегда, чтобы понять это.
Для повторных случаев использования, когда вы знаете, что вам придется делать это несколько раз, вы можете переопределить функцию popen и использовать ее как закрытый метод, который, как мне сказал тот же программист, является наилучшей практикой, если вы ожидаете кого-то другого будет заинтересован в поддержке кода позже, и вы не хотите, чтобы они с ним связывались.
def _popen(cmd):
proc_h = subprocess.Popen(cmd, stdin=subprocess.PIPE)
proc_h.wait(timeout=60)
return proc_h.poll() == os.EX_OK
Важно удалить stdout = subprocess.PIPE, если пользователю будет предложено ввести данные. В противном случае процесс зависает на 60 секунд, и пользователь не получает подсказку, и при этом он не понимает, что от него ожидается ввод пароля. Stdout естественным образом перейдет в окно оболочки и позволит пользователю передать ввод в popen ().
Кроме того, просто чтобы объяснить, почему вы возвращаете proc_h.poll () == os.EX_OK, он возвращает 0, если команда выполнена успешно. Это просто рекомендация в стиле c, когда вы хотите возвращать системные коды ошибок в случае сбоя функции, в то время как учёт того факта, что возвращаемый 0 будет интерпретироваться интерпретатором как «false».