Как я могу установить пароль пользователя в Linux из скрипта Python?

Я пытаюсь автоматизировать настройку доступа по SFTP. Этот скрипт работает от имени пользователя с правами sudo и без пароля.

Я могу создать пользователя так:

>>> import subprocess
>>> process = subprocess.Popen(['sudo', 'useradd', 'test'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> process.communicate()
('', '')

Далее мне нужно установить пароль пользователя, но я не могу понять, как это сделать. Вот что я пробовал.

>>> process = subprocess.Popen(['sudo', 'chpasswd'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> process.communicate('test:password')

В моей программе на Python это не действует, в интерактивном интерпретаторе оно блокируется после первой строки.

Как лучше всего это сделать?

Я использую Python 2.6 на Ubuntu Lucid.


person Jake    schedule 14.01.2011    source источник


Ответы (5)


В документации для communicate сказано, что вам нужно будет добавить stdin=PIPE, если вы отправляете данные на стандартный ввод через параметр communicate:

http://docs.python.org/release/2.6/library/subprocess.html#subprocess.Popen.communicate

Я понимаю, что это всего лишь скелетный код, но вот еще пара небольших комментариев на случай, если они вам пригодятся:

  • Если вас не интересуют выходные данные команды useradd, кроме того, была ли она неудачной или нет, вам может быть лучше использовать subprocess.check_call, которая вызовет исключение, если команда вернет ненулевое значение.
  • Во втором случае вы должны проверить, равно ли process.returncode 0 после вашего вызова communicate('test:password')
person Mark Longair    schedule 14.01.2011
comment
Спасибо за комментарии. Настоящий код на самом деле более тщательный, но не менее ценный. - person Jake; 14.01.2011

Попробуйте приведенный ниже код, который будет выполнять требуемую автоматизацию.

from subprocess import Popen, PIPE, check_call  
check_call(['useradd', 'test'])   
proc=Popen(['passwd', 'test'],stdin=PIPE,stdout=PIPE,stderr=PIPE)  
proc.stdin.write('password\n')  
proc.stdin.write('password')  
proc.stdin.flush()  
stdout,stderr = proc.communicate()  
print stdout  
print stderr

Операторы print необязательны.

person Senthil Murugan    schedule 04.12.2012

Вы забыли это:

stdin=subprocess.PIPE

Чтобы отправить данные в процесс, вам нужен файл stdin.

Итак, полное заявление:

process = subprocess.Popen(['sudo', 'chpasswd'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

а затем позвоните communicate('password').

person user225312    schedule 14.01.2011

В Ubuntu используйте пользовательский мод

class SomeClass
    def userPasswd(self, login, password):
        encPass = crypt.crypt(password)
        command = "usermod -p '{0:s}' {1:s}".format(encPass, login)
        result = os.system(command)
        if result != 0:
            logging.error(command)
        return result
person zarat    schedule 05.08.2015

Я предполагаю, что проблема в том, что вы забыли опцию -S для sudo.

person Candide Guevara Marino    schedule 27.09.2015