2009-02-19 10 views
33

Quindi sto cercando di ottenere un processo da eseguire come super utente da uno script python utilizzando il sottoprocesso. Nella shell ipython qualcosa comeesecuzione di un comando come super utente da uno script python

proc = subprocess.Popen('sudo apach2ctl restart', 
         shell=True, stdin=subprocess.PIPE, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE) 

funziona bene, ma non appena mi attengo in uno script che ho iniziare a ricevere: sudo: apach2ctl: command not found.

Direi che questo è dovuto al modo in cui sudo gestisce gli ambienti su ubuntu. (Ho anche provato sudo -E apche2ctl restart e sudo env path=$PATH apache2ctl restart con inutilmente)

Quindi la mia domanda è sostanzialmente, se voglio correre apache2ctl restart come super utente che richiede all'utente di inserire la password di super utente quando richiesto, come dovrei andare a fare Questo? Non ho intenzione di memorizzare le password nello script.

Edit:

ho provato passando i comandi come sia una stringa e token in una lista. Nell'interprete python, con una stringa otterrò il prompt della password correttamente (ancora non funziona in uno script python come nel mio problema originale), una lista dà solo la schermata di aiuto per sudo.

Edit 2:

Quindi quello che ho capito è che, mentre Popen lavorerà con alcuni comandi proprio come corde quando shell = True, ci vuole

proc = subprocess.Popen(['sudo','/usr/sbin/apache2ctl','restart']) 

senza 'shell = True' per ottenere sudo lavorare.

Grazie!

+2

Come configurare sudo in modo che questo utente possa eseguire solo questo comando senza richiedere una password? –

+0

Si potrebbe voler usare ['proc.wait()'] (https://docs.python.org/2/library/subprocess.html#subprocess.Popen.wait) a seconda di cosa si sta facendo; 'wait' non procede fino a quando il processo figlio non ha finito di funzionare. – craymichael

risposta

14

Provare a fornire il percorso completo di apache2ctl.

+0

Penso che ci abbiate colpito. L'esecuzione di uno script dall'interprete eredita $ PATH dalla shell interattiva che lo sta eseguendo. Quando viene eseguito come script, tuttavia, $ PATH è ereditato da una shell NON interattiva e potrebbe non essere lo stesso. È meglio specificare sempre percorsi completi quando si utilizza popen(). –

+0

Sì - ogni volta che fai riferimento ai file binari dagli script, non puoi fare affidamento sul fatto che $ PATH sia lì per te. A proposito, "apch2ctl" è errato. ;) – ojrac

3

devi usare Popen come questo:

cmd = ['sudo', 'apache2ctl', 'restart'] 
proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

Si aspetta una lista.

+7

Leggi http://docs.python.org/library/subprocess.html C'è una differenza tra un argomento stringa e sequenza quando shell = True. – jfs

+0

Ah, vedo, non l'ho mai usato prima. –

+1

Non impostare shell = True quando stai passando una lista in esso. –

21

Prova:

subprocess.call(['sudo', 'apach2ctl', 'restart'])

Il sottoprocesso ha bisogno di accedere al vero e proprio standard input/out/err per essere in grado di richiedere, e leggere la password. Se li imposti come pipe, devi inserire la password nella pipe.

Se non li definisce, poi afferra sys.stdout, ecc ...

7

Un altro modo è quello di rendere il vostro all'utente una password meno sudo user.

Digitare il seguente sulla riga di comando:

sudo visudo 

quindi aggiungere il seguente e sostituire il <username> con il vostro:

<username> ALL=(ALL) NOPASSWD: ALL 

Ciò permetterà all'utente di eseguire sudo comando senza dover chiedere password (compresa l'applicazione lanciata da detto utente.Questo potrebbe essere un rischio per la sicurezza anche se

Problemi correlati