Premier Training & Business Partner Red Hat

iPython – una shell tuttofare

Roberto Polli
Ti piacerebbe diventare anche tu uno di noi e
pubblicare i tuoi articoli nel blog degli RHCE italiani?

ipython

Nei corsi di Python tenuti per Extraordy, viene subito introdotto iPython: una shell interattiva che permette di lanciare sia comandi bash che istruzioni python.

Se nei corsi ne apprezziamo l’utilità didattica, in questo post vedremo come utilizzarla nel lavoro quotidiano e:

    1. eseguire i primi comandi python;
    2. velocizzare lo sviluppo del parsing dei file;
    3. tracciare dei grafici.

Installare ipython

Ipython è disponibile via EPEL, quindi una volta aggiunto il repository seguendo queste indicazioni, ci basta lanciare

# yum install ipython

La console mostra una serie di importanti informazioni e i comandi di help principali: teneteli bene a mente se state muovendo i primi passi con python!

#ipython
 Python 2.7.3 (default, Sep 26 2013, 20:03:06)
 Type "copyright", "credits" or "license" for more information.
IPython 0.12.1 -- An enhanced Interactive Python.
 ?         -> Introduction and overview of IPython's features.
 %quickref -> Quick reference.
 help      -> Python's own help system.
 object?   -> Details about 'object', use 'object??' for extra details.

Primi passi

Ci troviamo ora davanti il prompt che indica la prima linea di Input (In [1]) dove possiamo fare intanto un po’ di calcoli con le operazioni standard e bitwise

In [1]: print "quanto fa: ",  1024*1024 - (1<<20)
quanto fa: 0

Se ipython è in “echo mode” il comando print è opzionale ed il risultato di un’operazione verrà stampato a schermo prefissato dal prompt Out[numero riga].

In[2]: 10/2
Out[2]: 5

Di default le operazioni tra interi in python2 restituiscono un intero, quindi

In [4]: 5 / 2
Out[4]: 2

Per usare i decimali basta indicare che un valore è di tipo float, così

In [5]: 5.0 / 2
Out [5]: 2.5

Oppure definendo il comportamento globalmente con

In [6]: from __future__ import division

Per eseguire un comando in una shell (/bin/sh) basta anteporvi un punto esclamativo “!” – come fanno anche molti client ftp.

In [7]: ! ls -ld .
drwxr-x---+ 22 lug users 4096 Dec 16 11:04

Possiamo rieditare una riga inserita tramite la macro %edit che aprirà l’editor impostato nell’environment – analogamente alla bash-internal “fc”:

In [8]: %edit 5

Per uscire dall’editor bisogna salvare il file (con “:wq” nel caso di vim), mentre il contenuto verrà eseguito.

Per chiudere ipython invece basta premere CTRL+D, quindi Invio.

Sostituire la shell

Lanciamo ipython in modalità shell:

#ipython --profile=pysh

Ci accoglie un prompt leggermente diverso, con cui lanciare i soliti comandi:

lug@rpolli[~]|1> find . -maxdepth 1 -name .\* -type d
.
.ssh
.ipython
.local

Con ipython non ci facciamo mancare nulla, poichè supporta anche l’autocompletamento:

  • dei path;

  • degli eseguibili presenti nel PATH;

  • delle funzioni e dei moduli importati nella nostra sessione python.

In caso di conflitti (ad esempio l’eseguibile `file` e la classe `file` di python) vince quella nello scope di python. Se però il comando è preceduto da un “!” ipython utilizzerà sempre l’eseguibile presente nel path.

Catturare l’output

Ovviamente vorremmo anche catturarne l’output in una lista, cosa alquanto semplice. Basta usare il simbolo “!” davanti al comando da eseguire

lug@rpolli[~]|1> ret = !find . -maxdepth 1 -name .\* -type d
lug@rpolli[~]|15> ret
 ['.',
 './.ipython',
 './.ssh,
'./.local ]

Ora che abbiamo le nostre directory possiamo anche mostrarne il path assoluto (e normalizzato) utilizzando la funzione os.path.abspath del modulo os

lug@rpolli[~]|16>import os # carichiamo il modulo os per usarne le funzioni
lug@rpolli[~]|17>for directory_name in ret: print os.path.abspath(directory_name)
/home/lug
 /home/lug/.ipython
/home/lug/.ssh
/home/lug/.local

Fare delle statistiche sull’utilizzo della rete e’ molto semplice, perchè l’ouptut di ipython supporta

il metodo grep ed il metodo fields(), che ritorna l’n-mo campo:

ret = !ping -c10 -w10 www.google.com
ret = ret.grep("time=") # prendiamo solo le righe contenenti il tempo
rtt = ret.fields(7) #l'ottavo campo contiene il RTT
print (rtt)
['time=29.3', 'time=41.9', 'time=27.2', 'time=27.2', 'time=26.3', 'time=28.5', 'time=28.4', 'time=28.0', 'time=34.4', 'time=38.7']

Plottare

Se si è installato anche il pacchetto matplotlib, è possibile plottare i dati. Innanzitutto usiamo la macro %pylab per caricare le librerie necessarie.

>%pylab
Welcome to pylab, a matplotlib-based Python environment [backend: TkAgg].
 For more information, type 'help(pylab)'.

A questo punto possiamo plottare il contenuto della lista rtt, avendo cura di scartare i primi 5 caratteri che contengono “time=”. con x[5:]

> rtt = [ x[5:0] for x in rtt] # modifico ogni elemento di rtt scartando i primi 5 caratteri
> plot(rtt, legend="rtt in ms") # plotta la lista rtt
> legend(loc="lower left")
> title("Ping RTT www.google.it")

Conclusioni

In questo articolo spero di avervi incuriosito su python ed ipython. Fatemi sapere se vi è stato utile!

Info about author

Roberto Polli

Roberto works at Babel, migrating big mail infrastructures to open solutions. Develops in Python, C and Java to foster communities around various FLOSS, trying to bring both social and IT innovation. He's a RHCE and RHCVA, but loves maintaining free software, including the caldav java library: caldav4j. A life ago he took a Math degree, and he's really proud of it.