Использование sudo со скриптом Python

Имел эту же проблему.

Просто решил.

Это произошло после того, как NuGet был использован для установки Ext.NET, у которого есть зависимость от Newtonsoft.JSON. Уже был файл Newtonsoft.JSON.dll в / bin (и, очевидно, ссылка на него в файле web.config), без проверки. Я начал процедуру установки пакета NuGet во время отладки (так что файл, вероятно, имел блокировку).

В окне ошибки времени выполнения он расскажет вам о трассировке стека, в какой части манифеста есть проблема, у меня была основная версия, поэтому я проверил версию пакета установки. и это была 1 основная версия. Найден исходный файл NuGet: «[fизический путь] /../ packages / Newtonsoft.Json. [Версия] / lib / [. Net version] /"

Оба манифеста и библиотека были там так скопированы

Сэмплы кода: До

<dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
    <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>

После

<dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
    <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>

Надеюсь, это поможет

29
задан Roman Rdgz 24 October 2012 в 08:37
поделиться

10 ответов

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')

29
ответ дан Aniket Inge 24 October 2012 в 08:37
поделиться

Пожалуйста, попробуйте модуль 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 !")
1
ответ дан user2951688 24 October 2012 в 08:37
поделиться

Я использовал это для Python 3.5. Я сделал это с помощью модуля подпроцесса . Использование такого пароля очень небезопасно .

Модуль подпроцесса принимает команду как список строк, поэтому либо создайте список заранее, используя split () , либо пропустите весь список позже. Прочитайте документацию для получения дополнительной информации.

#!/usr/bin/env python
import subprocess

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

cmd1 = subprocess.Popen(['echo',sudoPassword], stdout=subprocess.PIPE)
cmd2 = subprocess.Popen(['sudo','-S'] + command, stdin=cmd1.stdout, stdout=subprocess.PIPE)

output = cmd2.stdout.read.decode()
2
ответ дан Ajax1234 24 October 2012 в 08:37
поделиться

Чтобы передать пароль в стандартный ввод sudo:

#!/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 без пароля вместо жесткого ввода пароля в исходном коде.

16
ответ дан jfs 24 October 2012 в 08:37
поделиться
  • Используйте опцию -S в команде sudo, которая говорит, что нужно читать пароль из 'stdin' вместо оконечного устройства.

  • Скажите Попену, чтобы он читал stdin из PIPE.

  • Отправьте пароль на стандартную ТРУБУ процесса, используя его в качестве аргумента для передачи метода. Не забудьте добавить символ новой строки '\ n' в конце пароля.

sp = Popen(cmd , shell=True, stdin=PIPE)
out, err = sp.communicate(_user_pass+'\n')   
3
ответ дан tripleee 24 October 2012 в 08:37
поделиться

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

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

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

3
ответ дан mensi 24 October 2012 в 08:37
поделиться

Многие ответы сосредоточены на том, как заставить ваше решение работать, в то время как очень немногие предполагают, что ваше решение - очень плохой подход . Если вы действительно хотите «практиковаться, чтобы учиться», почему бы не практиковаться, используя хорошие решения? Жесткое кодирование вашего пароля изучает неправильный подход!

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

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

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

  • Редактируйте /etc/sudoers для разрешите вашему пользователю использовать sudo без ввода пароля.

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

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

46
ответ дан MestreLion 24 October 2012 в 08:37
поделиться

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

os.popen("sudo -S %s"%(command), 'w').write('mypass\n')
0
ответ дан laalto 24 October 2012 в 08:37
поделиться

Я знаю, что всегда предпочтительнее не кодировать пароль sudo в скрипте. Однако по какой-то причине, если у вас нет разрешения на изменение /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
0
ответ дан Jeremy Kao 24 October 2012 в 08:37
поделиться

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

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

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

1
ответ дан crizCraig 24 October 2012 в 08:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: