Używanie sudo ze skryptem Pythona

Próbuję napisać mały skrypt, aby zamontować folder udostępniony VirtualBox za każdym razem, gdy wykonuję skrypt. Chcę to zrobić z Pythonem, ponieważ staram się nauczyć go skryptów.

Problem polega na tym, że potrzebuję uprawnień do uruchomienia polecenia mount. Mogę uruchomić skrypt jako sudo, ale wolę, aby sudo samodzielnie.

Już wiem, że zapisywanie hasła do pliku. py nie jest bezpieczne, ale mówimy o maszynie wirtualnej, która wcale nie jest krytyczna: po prostu chcesz kliknąć skrypt. py i uruchomić go.

To moja próba:

#!/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)

Moja wersja Pythona to 2.6

Author: Roman Rdgz, 2012-10-24

10 answers

sudoPassword = 'mypass'
command = 'mount -t vboxsf myfolder /home/myuser/myfolder'
p = os.system('echo %s|sudo -S %s' % (sudoPassword, command))
Spróbuj tego i daj mi znać, czy zadziała. :-)

I ten:

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

 24
Author: Aniket Inge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-24 09:03:08

Wiele odpowiedzi koncentruje się na tym, jak sprawić, by Twoje rozwiązanie działało, podczas gdy niewiele sugeruje, że Twoje rozwiązanie jest bardzo złym podejściem {14]} . Jeśli naprawdę chcesz "ćwiczyć, aby się uczyć", dlaczego nie ćwiczyć przy użyciu dobrych rozwiązań? Hardcoding Twoje hasło uczy się błędnego podejścia !

Jeśli naprawdę chcesz mniej hasła mount do tego woluminu, może {[1] }nie jest w ogóle potrzebne ! Mogę zaproponować inne podejście?

  • Use /etc/fstab jak zasugerował mensi. Użyj opcji user i noauto, aby umożliwić zwykłym użytkownikom montowanie tego woluminu.

  • Użyj Polkit dla akcji bez hasła: Skonfiguruj plik .policy dla skryptu za pomocą <allow_any>yes</allow_any> i upuść na /usr/share/polkit-1/actions

  • Edytuj /etc/sudoers, aby umożliwić użytkownikowi korzystanie z sudo bez wpisywania hasła.

Wszystkie powyższe zezwalają na uprawnienia roota bez hasła, żadne nie wymaga kodowania na twardo hasła. Wybierz dowolne podejście i mogę to wyjaśnić w więcej szczegóły.

 37
Author: MestreLion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:39

Aby przekazać hasło do sudo's 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]

Uwaga: Możesz prawdopodobnie skonfigurować bez hasła sudo lub SUDO_ASKPASS zamiast kodować hasło na twardo w kodzie źródłowym.

 15
Author: jfs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-17 04:18:08

subprocess.Popen tworzy proces i otwiera rury i takie tam. To co robisz to:

  • rozpocznij proces sudo -S
  • rozpocznij proces mypass
  • rozpocznij proces mount -t vboxsf myfolder /home/myuser/myfolder
Co oczywiście nie zadziała. Musisz przekazać argumenty Popenowi. Jeśli spojrzysz na jego dokumentację , zauważysz, że pierwszy argument jest w rzeczywistości listą argumentów.
 2
Author: mensi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-24 08:45:13
  • Użyj opcji-S w poleceniu sudo, które mówi, aby odczytać hasło z 'stdin' zamiast urządzenia końcowego.

  • Powiedz Popenowi, żeby odczytał stdin z PIPE ' a.

  • Wyślij hasło do rury stdin procesu, używając go jako argumentu do komunikacji metody. Nie zapomnij dodać nowego znaku linii,' \n', na końcu hasła.

sp = Popen(cmd , shell=True, stdin=PIPE)
out, err = sp.communicate(_user_pass+'\n')   
 2
Author: Hubert Vijay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-01 10:46:02

Aby ograniczyć to, co uruchamiasz jako sudo, możesz uruchomić

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

Bez konieczności przechowywania hasła. Parametr -E przekazuje ENV bieżącego użytkownika do procesu. Zauważ, że Twoja powłoka będzie miała sudo priveleges po drugim poleceniu, więc używaj ostrożnie!

 1
Author: crizCraig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-07 21:55:46

Czasami wymagają zwrotu powozu:

os.popen("sudo -S %s"%(command), 'w').write('mypass\n')
 0
Author: user2095717,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-27 14:16:10

Proszę wypróbować moduł pexpect. Oto Mój kod:

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 !")
 0
Author: user2951688,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-07 07:24:34

Wiem, że zawsze lepiej nie kodować na twardo hasła sudo w skrypcie. Jednak z jakiegoś powodu, jeśli nie masz uprawnień do modyfikacji /etc/sudoers lub zmiany właściciela pliku, pexpect jest wykonalną alternatywą.

Oto funkcja Pythona sudo_exec w celach informacyjnych:

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
Author: Jeremy Kao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-29 09:38:35

Użyłem tego dla Pythona 3.5. Zrobiłem to używając podproces Moduł.Używanie takiego hasła jest bardzo niebezpieczne .

Moduł podprocesu przyjmuje polecenie jako listę łańcuchów znaków, więc albo utwórz listę wcześniej za pomocą split(), albo przekaż całą listę później. Przeczytaj dokumentację, aby uzyskać więcej informacji.

#!/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()
 0
Author: Nandesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-01 22:28:22