Я пишу сценарий python, который выполняет сценарий csh в Solaris 10. Сценарий csh запрашивает у пользователя пароль root (который я знаю), но я не уверен, как заставить сценарий python ответить на запрос паролем. Это возможно? Вот что я использую для выполнения скрипта csh:
import commands
commands.getoutput('server stop')
Впервые вижу используемые команды. Кстати, вы можете использовать модуль getpass, чтобы получить пароль из командной строки, не отображая его.
Должна быть возможность передать его как параметр. что-то типа:
commands.getoutput('server stop -p password')
наш сценарий остановки сервера не имеет флага -p и, скорее всего, не получит его.
Используйте подпроцесс. Вызовите Popen (), чтобы создать свой процесс, и используйте commun (), чтобы отправить ему текст. Извините, забыл включить ТРУБУ ..
from subprocess import Popen, PIPE
proc = Popen(['server', 'stop'], stdin=PIPE)
proc.communicate('password')
Вам лучше избегать пароля и попробовать такую схему, как sudo и sudoers. Pexpect, упомянутый в другом месте, не является частью стандартной библиотеки.
Похоже, это не работает. Я продолжу исследовать popen.
Я получаю такой же ответ при использовании PIPE, как вы рекомендуете здесь. Сценарий останавливается с приглашением Пароль :.
Я не думаю, что это сработает, потому что сценарий csh выполняет команду su root -c "$ cmd0 $ *", чтобы попытаться выполнить su для получения root-прав. Процесс su будет отличаться от сценария остановки сервера.
Кажется, это работает лучше:
import popen2
(stdout, stdin) = popen2.popen2('server stop')
stdin.write("password")
Но это еще не 100%. Несмотря на то, что "пароль" - правильный пароль, я все еще получаю su: Извините, из сценария csh, когда он пытается выполнить su для получения root-прав.
Я думаю, вы перевернули stdin и stdout.
Нет, из API: возвращает файловые объекты (child_stdout, child_stdin)
К вашему сведению - popen2: «Не рекомендуется, начиная с версии 2.6: этот модуль устарел. Используйте модуль подпроцесса. Особенно проверьте раздел« Замена старых функций с модулем подпроцесса ».
Да, я только что это заметил. Я переключил свой код обратно на модуль подпроцесса. Спасибо!
@darrick: Я неправильно сослался на os.popen2 вместо popen2.popen2. Как ни странно, порядок stdin и stdout в двух библиотеках разный ...
Взгляните на модуль ожидание. Он предназначен для работы с интерактивными программами, что похоже на ваш случай.
Да, и помните, что жестко закодированный пароль root в сценарии оболочки или python потенциально является дырой в безопасности: D
Да, pexpect был подходящим вариантом ... Я опубликовал ответ в конце этой ветки.
Чтобы избежать необходимости отвечать на вопрос о пароле в скрипте python, я просто буду запускать скрипт от имени пользователя root. На этот вопрос все еще нет ответа, но я думаю, что пока сделаю это так.
Не могли бы вы очистить и обобщить свои ответы?
import pexpect
child = pexpect.spawn('server stop')
child.expect_exact('Password:')
child.sendline('password')
print "Stopping the servers..."
index = child.expect_exact(['Server processes successfully stopped.', 'Server is not running...'], 60)
child.expect(pexpect.EOF)
Сделали свое дело! Правила Pexpect!
Добавьте input=
в proc.communicate()
, чтобы запустить его, для парней, которым нравится использовать стандартную библиотеку.
from subprocess import Popen, PIPE
proc = Popen(['server', 'stop'], stdin=PIPE)
proc.communicate(input='password')
Я пропустил PIPE, новая версия работает ...