PDA

View Full Version : [Python/Linux] Redirect stdout


demos88
09-11-2012, 15:58
Ciao, lavorando a un progetto universitario mi sono trovato di fronte a un problema relativo all'apertura da python di subprocessi e gestione del relativo output.
Ecco il codice (grammatica del Python 3.2):

slurm = Popen("salloc -c1 -n1 ",shell=True,stdin=PIPE,stdout=PIPE)
slurm.stdin.write(bytes("srun java -jar /path/to/jarfile/jarfile.jar &\n",'ascii'))
print (str(slurm.stdout.readline(),'ascii'))

Come qualcuno può avere intuito, ho a che fare con SLURM (https://computing.llnl.gov/linux/slurm/) la cui conoscenza comunque non è indispensabile per risolvere il mio problema.
Nella prima riga domando l'allocazione di un nodo usando il metodo Popen() di Python avviando un subprocesso, nella seconda passo al subprocesso il comando srun per avviare il jar che mi interessa.
La terza riga è di debug per vedere cosa effettivamente leggo dalla pipe del processo.
Il mio problema è semplice: con Popen apro praticamente una shell nella quale eseguo i comandi salloc e srun. Però quando eseguo salloc, ottengo in console l'output che invece non vorrei visualizzare ma catturare con la pipe e processare (perchè l'output di salloc mi dice l'id del job allocato, e mi serve).
Invece l'output del file jar non viene mandato in console e lo posso leggere leggendo l'stdout del processo.

Quello che serve a me è che anche l'output di salloc venga nascosto alla console più "alta" (quella dello script python) e venga letto mediante lo stdout del processo avviato dallo script. Penso che il punto cruciale sia il fatto che il comando salloc avvia un ulteriore subprocesso al subprocesso, che quindi è un sub-subprocesso dello script più esterno.

Spero di essere stato abbastanza chiaro, non sono molto esperto dell'ambiente linux :doh:
Grazie

cdimauro
09-11-2012, 20:21
Ho lavorato poco col modulo subprocess, e non posso fare qualche prova con Linux.

Comunque su due piedi, potresti provare a leggere l'output subito dopo che hai lanciato il comando salloc?

Per adesso commenta tutte le altre righe, e vedi se riesci a intercettare l'output di salloc. Fatto questo, poi aggiungerai le rimanenti righe.

Altra cosa, mi sembra che ci sia qualche funziona (o metodo di Popen, purtroppo non ricordo bene adesso) che ti consente di lanciare un comando e di recuperare l'output. Può darsi che sia sufficiente per quello che ti serve.

demos88
09-11-2012, 22:22
Comunque su due piedi, potresti provare a leggere l'output subito dopo che hai lanciato il comando salloc?

Per adesso commenta tutte le altre righe, e vedi se riesci a intercettare l'output di salloc. Fatto questo, poi aggiungerai le rimanenti righe.

L'avevo già provato questo stratagemma ma non trovo l'output di salloc nel stdout del subprocesso. L'output di salloc, che presumo non venga da salloc in se, ma da un demone avviato da salloc, che è quindi un altro processo (che potrei definire il sub-subprocesso), me lo trovo invece nella console da cui lancio lo script python, è come se bypassasse il stdout del suprocesso.
Insomma, l'output del demone lanciato da salloc me lo becco direttamente nella shell più esterna e ignora la pipe del suprocesso (quello che ho chiamato "slurm").

Altra cosa, mi sembra che ci sia qualche funziona (o metodo di Popen, purtroppo non ricordo bene adesso) che ti consente di lanciare un comando e di recuperare l'output. Può darsi che sia sufficiente per quello che ti serve.
Si, è il communicate() se non sbaglio. Il comando ha però un "problema": trasferisce una stringa (il comando) e ne riceve l'output, ma poi killa il subprocesso. Infatti se lo uso, ottengo pure la notifica della revoca dell'allocazione (quando il subprocesso muore, il manager slurm considera terminato il job e lo chiude...). E invece a me serve tenere allocato il nodo del cluster per tempo indeterminato per eseguire un arbitrario numero di srun (per questo uso slurm.stdin.write(), che è un modo di comunicare un po' più "grezzo" ).

Una bella gatta da pelare eh? :asd:
Purtroppo è inerente la mia tesi di laurea per cui devo riuscirci in qualche modo! grazie per la risposta :)

marco.r
09-11-2012, 22:37
la mia ipotesi e' che il programma scriva su stderr invece che stdout.
hai provato a impostare un canale diverso per stderr ?
Il fatto che sia un sottoprocesso di un altro processo e' irrilevante, penso. Standard input e output vengono solitamente "ereditati" dal processo padre.

cdimauro
10-11-2012, 06:24
Idem. Non mi vengono in mente altre possibilità, proprio perché i descrittori dei file sono condivisi, per cui tutto dovrebbe poter essere controllabile da subprocess.

Ma è strano che un programma o demone utilizzi stderr per quello che dovrebbe essere un normale output, per lo meno da quel che ha descritto demos88. In genere lo si usa per warning ed errori...

demos88
10-11-2012, 13:24
la mia ipotesi e' che il programma scriva su stderr invece che stdout.
hai provato a impostare un canale diverso per stderr ?
Il fatto che sia un sottoprocesso di un altro processo e' irrilevante, penso. Standard input e output vengono solitamente "ereditati" dal processo padre.
OMG u are a fcking genious!
Scriveva proprio nell'stderr! :eek:
Ora riesco a catturare e gestire l'output!

Idem. Non mi vengono in mente altre possibilità, proprio perché i descrittori dei file sono condivisi, per cui tutto dovrebbe poter essere controllabile da subprocess.

Ma è strano che un programma o demone utilizzi stderr per quello che dovrebbe essere un normale output, per lo meno da quel che ha descritto demos88. In genere lo si usa per warning ed errori...
Infatti non mi sarebbe mai venuto in mente di pensare all'stderr che non era mio interesse gestire in modo particolare in quanto è forse più comodo averlo come output diretto per un debug più veloce, almeno in fase di progettazione (tanto gli script sono usati da dottorandi...).

Grazie a entrambi per le risposte, erano due giorni che stavo fermo su questo punto. :yeah: