Запустите команду Linux из Python, который требует ввода пользователя - PullRequest
0 голосов
/ 15 мая 2018

У меня есть следующий код Python:

import subprocess
p=subprocess.Popen(["openssl","genrsa","-aes256","-out","ise.key.pem","2048"],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
inputdata="123456"
p.communicate(input=inputata)
p.communicate(input=inputata)

Вывод приведенного выше кода:

    pan@pan:~/python-scripts$ Generating RSA private key, 2048 bit long modulus
........................+++
...................................+++
e is 65537 (0x10001)
Enter pass phrase for ise.key.pem:
User interface error
140617148802712:error:0906906F:PEM routines:PEM_ASN1_write_bio:read key:pem_lib.c:379:

Я хочу, чтобы ввод был предоставлен Python, не должно быть никакого взаимодействия с пользователем:

Я знаю, что сертификат может быть сгенерирован библиотекой python pyOpenSSL, но я хочу использовать обычную команду linux

Моя версия Python :

Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "enter code here`license" for more information.

Я увидел следующую ссылку, но она не помогла

Python выполняет командную строку, отправляя ввод и читая вывод

Если вы запускаете команду в оболочке, она выполняется следующим образом:

pan@pan:~/python-scripts$ openssl genrsa -aes256 -out ise.key.pem 2048
Generating RSA private key, 2048 bit long modulus
..............................................................+++
..+++
e is 65537 (0x10001)
Enter pass phrase for ise.key.pem:
Verifying - Enter pass phrase for ise.key.pem:

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Я обычно не люблю подпроцесс для такого рода задач ... Я бы предпочел использовать pexpect для эмуляции поведения человека (ввод данных ... и т. Д.).

Это пример грубого выполнения работы

import pexpect

def main():
        inputdata="123456"
        c = pexpect.spawn("/usr/bin/openssl", ["genrsa","-aes256","-out","ise.key.pem","2048"])
        c.expect("Enter.*:")
        c.sendline(inputdata)
        c.expect("Verifying.*:")
        c.sendline(inputdata)
        c.expect(pexpect.EOF)
        c.close()
        c.kill(0)
        print "Done"

if __name__=='__main__':
        main()
0 голосов
/ 16 мая 2018

В своем комментарии Жан-Франсуа Фабр прав об этом:

Но реальная проблема заключается в том, что ввод по трубопроводу в процедуру ввода пароля не всегда работает.

Но не об этом:

Вы должны генерировать событие клавиатуры на более низком уровне.

Хотя это было бы в общем случае, в случае приВручную команду openssl genrsa … предлагает опцию -passout stdin до чтения пароля со стандартного ввода :

openssl genrsa -aes256 -out ise.key.pem -passout stdin 2048

Итак, этоСценарий Python работает:

import subprocess
p=subprocess.Popen(["openssl","genrsa","-aes256","-out","ise.key.pem",
                    "-passout","stdin","2048"], stdin=subprocess.PIPE,
                                                stdout=subprocess.PIPE)
inputdata="123456"
p.communicate(input=inputdata)

Обратите внимание, что нельзя communicate() с timeout = None более одного раза, так как он ожидает процессапрекратить .Но в этом нет необходимости, потому что с -passout stdin команда не запрашивает подтверждение, поэтому нет необходимости вводить фразу-пароль во второй раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...