Python — Как получить вывод команды Sudo с помощью Popen

#python #linux #macos #sudo

#python #linux #macos #sudo

Вопрос:

sudo команда проверяет пароль пользователя на соответствие имени пользователя. Я пишу простую программу, которая проверяет, действителен ли ввод пользователя в соответствии с sudo командой. Я использую -S тег для того, чтобы передавать входные данные извне, и я использую Popen() для запуска скрипта:

 import getpass
import subprocess
import time

password = getpass.getpass()
proc = subprocess.Popen('sudo -k -S -l'.split(), stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
output = proc.communicate(password.encode())
print(f'This is the value of the output {output[0]}')
  

Если пользователь вводит неправильный пароль в getpass.getpass() , мне нужно проверить его на соответствие фактическому паролю пользователя. В этом случае sudo должен выводить Sorry Please Try Again . Не мог бы кто-нибудь, пожалуйста, сообщить мне, как я могу прочитать эту ошибку?

Когда я запускаю это в терминале:

 ➜  Desktop python3.8 test.py
Password: 
Sorry, try again.
This is the value of the output b''
  

Спасибо, приветствия, и я действительно ценю вашу помощь.

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

1. Команда застревает, и ничего не происходит

Ответ №1:

В документации Python говорится:

Обратите внимание, что если вы хотите отправить данные в stdin процесса, вам необходимо создать объект Popen с помощью stdin=PIPE.

Поэтому используйте

 proc = subprocess.Popen(['sudo', '-S', '-l'], stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
  

разрешить ввод пароля с помощью communicate , в противном случае он просто ждет, пока вы введете его на терминале (без запроса, поскольку он записывается).

Любые сообщения об ошибках доступны в output переменной, в частности output[1] , которая соответствует stderr.

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

1. Да, я пробовал это, и теперь он принимает входные данные, однако, как я могу записать «Извините, пожалуйста, попробуйте еще раз»?

2. Вы уже записали это. Это в вашей output переменной, но в output[1] то время как вы только что просмотрели output[0]

3. большое спасибо, какой сейчас был бы допустимый метод подтверждения неправильного пароля? вывод, когда я пишу неправильный пароль, выглядит следующим образом [sudo] password for tejas: [sudo] password for tejas: sudo: no password was provided sudo: 1 incorrect password attempt

4. Вы можете установить переменную среды LC_ALL=C , чтобы убедиться, что язык всегда один и тот же, а затем, например, сопоставить подстроку "incorrect password" . Надеюсь, со временем это будет достаточно стабильно. Не уверен, зачем вы вообще пытались это сделать, но это другой вопрос.