Подтвердить что ты не робот

Использование sudo с Python script

Я пытаюсь написать небольшой script, чтобы монтировать общую папку VirtualBox каждый раз при выполнении script. Я хочу сделать это с Python, потому что я пытаюсь изучить его для создания сценариев.

Проблема в том, что мне нужны привилегии для запуска команды mount. Я мог бы запустить script как sudo, но я предпочитаю, чтобы он сделал sudo самостоятельно.

Я уже знаю, что безопасно писать пароль в файл .py, но мы говорим о виртуальной машине, которая не критична вообще: я просто хочу щелкнуть .py script и получить ее работа.

Это моя попытка:

#!/usr/bin/env python
import subprocess

sudoPassword = 'mypass'
command = 'mount -t vboxsf myfolder /home/myuser/myfolder'

subprocess.Popen('sudo -S' , shell=True,stdout=subprocess.PIPE)
subprocess.Popen(sudoPassword , shell=True,stdout=subprocess.PIPE)
subprocess.Popen(command , shell=True,stdout=subprocess.PIPE)

Моя версия python 2.6

4b9b3361

Ответ 1

sudoPassword = 'mypass'
command = 'mount -t vboxsf myfolder /home/myuser/myfolder'
p = os.system('echo %s|sudo -S %s' % (sudoPassword, command))

Попробуйте это и сообщите мне, если это сработает.: -)

И этот:

os.popen("sudo -S %s"%(command), 'w').write('mypass')

Ответ 2

Во многих ответах основное внимание уделяется тому, как заставить ваше решение работать, в то время как очень немногие говорят о том, что ваше решение - это подход очень плохой. Если вы действительно хотите "научиться учиться", почему бы не использовать хорошие решения? Hardcoding ваш пароль изучает неправильный подход!

Если то, что вы действительно хотите, это mount без пароля для этого тома, возможно, sudo не требуется вообще! Могу ли я предложить другие подходы?

  • Используйте /etc/fstab как mensi. Используйте опции user и noauto, чтобы обычные пользователи монтировали этот том.

  • Используйте Polkit для действий без пароля: настройте файл .policy для вашего script с помощью <allow_any>yes</allow_any> и оставьте на /usr/share/polkit-1/actions

  • Измените /etc/sudoers, чтобы позволить вашему пользователю использовать sudo без ввода пароля.

Все вышеперечисленное допускает привилегию rootless root, никто не требует жесткого кодирования вашего пароля. Выберите любой подход, и я могу объяснить его более подробно.

Ответ 3

Чтобы передать пароль в sudo stdin:

#!/usr/bin/env python
from subprocess import Popen, PIPE

sudo_password = 'mypass'
command = 'mount -t vboxsf myfolder /home/myuser/myfolder'.split()

p = Popen(['sudo', '-S'] + command, stdin=PIPE, stderr=PIPE,
          universal_newlines=True)
sudo_prompt = p.communicate(sudo_password + '\n')[1]

Примечание. Возможно, вы могли бы сконфигурировать пароль без пароля sudo или SUDO_ASKPASS вместо жесткого кодирования вашего пароля в исходном коде.

Ответ 4

subprocess.Popen создает процесс и открывает трубы и прочее. Что вы делаете:

  • Запустите процесс sudo -S
  • Запустите процесс mypass
  • Запустите процесс mount -t vboxsf myfolder /home/myuser/myfolder

который, очевидно, не будет работать. Вам нужно передать аргументы Popen. Если вы посмотрите свою документацию, вы заметите, что первый аргумент на самом деле является списком аргументов.

Ответ 5

иногда требуется возврат каретки:

os.popen("sudo -S %s"%(command), 'w').write('mypass\n')

Ответ 6

Попробуйте модуль pexpect. Вот мой код:

import pexpect
remove = pexpect.spawn('sudo dpkg --purge mytool.deb')
remove.logfile = open('log/expect-uninstall-deb.log', 'w')
remove.logfile.write('try to dpkg --purge mytool\n')
if remove.expect(['(?i)password.*']) == 0:
    # print "successfull"
    remove.sendline('mypassword')
    time.sleep(2)
    remove.expect(pexpect.EOF,5)
else:
    raise AssertionError("Fail to Uninstall deb package !")

Ответ 7

Я знаю, что всегда рекомендуется не печатать пароль sudo в script. Однако по какой-либо причине, если у вас нет разрешения на изменение /etc/sudoers или изменить владельца файла, Pexpect является приемлемой альтернативой.

Ниже приведена функция Python sudo_exec для вашей справки:

import platform, os, logging
import subprocess, pexpect

log = logging.getLogger(__name__)

def sudo_exec(cmdline, passwd):
    osname = platform.system()
    if osname == 'Linux':
        prompt = r'\[sudo\] password for %s: ' % os.environ['USER']
    elif osname == 'Darwin':
        prompt = 'Password:'
    else:
        assert False, osname

    child = pexpect.spawn(cmdline)
    idx = child.expect([prompt, pexpect.EOF], 3)
    if idx == 0: # if prompted for the sudo password
        log.debug('sudo password was asked.')
        child.sendline(passwd)
        child.expect(pexpect.EOF)
return child.before

Ответ 8

  • Используйте параметр -S в команде sudo, которая сообщает, чтобы прочитать пароль из "stdin" вместо терминального устройства.

  • Скажите Popen, чтобы прочитать stdin из PIPE.

  • Отправьте пароль в stdin PIPE процесса, используя его в качестве аргумента для способа передачи. Не забудьте добавить новый символ строки "\n" в конце пароля.

sp = Popen(cmd , shell=True, stdin=PIPE)
out, err = sp.communicate(_user_pass+'\n')   

Ответ 9

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

python non_sudo_stuff.py
sudo -E python -c "import os; os.system('sudo echo 1')"

не требуя сохранения пароля. Параметр -E передает текущему пользовательскому env процессу. Обратите внимание, что после второй команды ваша оболочка будет иметь sudo priveleges, поэтому используйте ее с осторожностью!