Я использую OpenVPN в своей компании и пытаюсь автоматизировать процесс создания пользователей. Возникла проблема на этапе генерации сертификата, с которой я столкнулся сейчас. При попытке построить ключ для пользователя (все параметры предопределены) программа должна несколько раз нажать Enter и в конце 2 раза "y" и "Enter". Я пытался использовать Popen и PIPE, но пока безуспешно. Был бы признателен за любую информацию.
import sys, os
from subprocess import Popen, PIPE
# Generate an .ovpn file
try:
username = sys.argv[1]
except:
print "Error. Supply a username!"
sys.exit()
print("Adding user")
os.system("useradd" + " -m" + " -s" + " /bin/bash" + username)
print("Sourcing vars")
os.system('source + /home/myuser/openvpn-ca/vars')
enter = Popen(['/home/myuser/openvpn-ca/build-key {}'.format(username)]),
stdin=PIPE, shell=True)
enter.communicate(input='\n')
Редактировать:
Это отличается от того, для чего он был помечен как [дубликат]. Вот почему:
Мне не нужно генерировать пользовательский сертификат, изменять какие-либо значения и т. д. Мне просто нужно нажать «Ввод» несколько раз и ввести «да» и «Ввод» 2 раза.
🤔 А знаете ли вы, что...
Python подходит для начинающих программистов благодаря своей простоте и читаемости кода.
Вы не можете source
скрипт оболочки из Python; точнее, вы можете, но он просто запустит новый подпроцесс, который sources
что-то и затем исчезнет, ничего не изменив в вашей среде Python или последующих подпроцессах.
Вместо этого попробуйте что-то вроде этого:
import sys
import logging # to get diagnostics on standard error instead
import subprocess
# Maybe switch to level=logging.WARNING once you are confident this works
logging.basicConfig(level=logging.INFO, format='%(module)s:%(asctime)s:%(message)s')
try:
username = sys.argv[1]
except:
logging.error("Error. Supply a username!")
sys.exit()
logging.info("Adding user")
subprocess.run(["useradd", "-m", "-s", "/bin/bash", username],
check=True, universal_newlines=True)
logging.info("Building key")
subprocess.run('''
source /home/myuser/openvpn-ca/vars
/home/myuser/openvpn-ca/build-key {}'''.format(username),
shell=True, check=True, input='\n\n', universal_newlines=True)
Для переключения на subprocess.run()
требуется достаточно новая версия Python 3. В более старых версиях subprocess.check_call()
делала примерно то же самое, но не имела аргумента input=
, так что вам действительно приходилось использовать для этого базовый Popen()
.
Дополнительные примечания:
source
явно был синтаксической ошибкой.check=True
, чтобы убедиться, что Python проверяет успешность выполнения команд.os.system()
с subprocess
— это не ошибка, а подозрительный запах кода.(Намного) больше об использовании subprocess
на U*x здесь: https://stackoverflow.com/a/51950538/874188