giovedì 22 novembre 2007

screen: terminale multitasking!

Unix (ed i sistemi Unix-Like) è un sistema operativo multitasking e multiutente. L'interfaccia utente "preferenziale" di Unix è una Shell che gira su un terminale. La Shell è un'interfaccia a caratteri del tipo "linea di comando". Passi che più utenti si possono collegare contemporaneamente al sistema attraverso terminali, ma come fà un singolo utente a far girare più programmi sulla sua shell? Oggi come oggi, nell'era della finestra, sembra impossibile vero? Forse a qualcuno anche inutile!? Avvio il mio bel Server X col mio Desktop/Window Manager preferito e sono a cavallo!... e se mi devo connettere da remoto con ssh ad esempio?!? Situazione, questa, che emula bene l'uso dei vecchi terminali fisici. Nessun problema, una soluzione è screen!

Una delle "sciccherie" di screen è prorio quella di fornirci un terminale multitasking. Cioè un terminale in cui possiamo eseguire più programmi contemporaneamente. Passando dall'uno all'altro senza problemi e, sopratutto, senza interrompere il loro funzionamento.

Screen lavora a sessioni. Una sezione di screen può contenere diversi programmi in esecuzione (processi). Una sezione "nasce" con una chiamata a screen. Una sezione "muore" con la chiusura dell'ultimo processo ad essa associato.
Screen avvia una nuova sessione quando lo si chiama specificando un programma da avviare o senza nessun parametro (in questo caso avvia una istanza della shell di default *).
:~$screen
Avvio una finestra contenente una shell.
:~$screen joe
Avvio una finestra contenente joe.
Consideriamo screen come un gestore di finistre a tutto schermo. Ogni finestra contine un programma. Una sessione contiene più finestre (almeno una).
Passo successivo, necessario prima di passare ad un poco di pratica, è capire la relazione tra sessione e soket. Chiariamoci da subito che questa nomenclatura è propria di screen e, quindi, può risultare ingannevole:
  • Soket: ciò che screen chiama soket è in relatà, per il SO, una PIPE con nome.
  • Sessione: una sessione di screen non è altro che un processo del SO che esegue screen.
Fatti i dovuti chiarimenti ora continuiamo ad usare la terminologia di screen. Per screen ogni sessione è associata ad un socket. Questo fatto è necessario per un uso più avanzato di screen di quello che voliamo fare noi, almeno per ora. Tuttavia dovremo comunque conoscere questo aspetto per poter controllare le sessioni che andiamo ad avviare. Allora, schematizzando:
1 soket=>1 sessione=> N finestre=> N programmi.
Per ragioni di sicurezza evitate sempre di abbandonare il sistema con sessioni di screen aperte. Chiudetele tutte se lasciate la macchina accessa, e sopratutto se rimane connessa alla rete. Screen è molto potente ma comporta dei rischi. Questo non deve scoraggiare il suo uso ovviamente. Per ora teniamoci a mente che screen non realizza soltanto un terminale multitasking.

Passiamo alla pratica:
Abbiamo visto due maniere per avviare screen. Per ora, onde evitare confusioni, useremo quella con parametro. Usiamo un programma "vistoso", tipo mc, per aiutarci.
:-$screen mc
A prima vista è tutto come se avessimo avviato normalmente mc. Ora però premiamo ctrl+a e successivamente d. Vedremo che torniamo alla shell di "partenza" con questo output:
:~$ screen mc
[detached]
:~$
Che cosa è successo?
  • Abbiamo, tramite il primo comando, avviato una sessione di screen nella quale la prima finestra contiene un mc.
  • Abbiamo usato un comando interattivo di screen per distaccare la sessione dal terminale.
Questo secondo punto merita delle spiegazioni. Per "comandare" le finestre di screen non si usa il mouse ma la tastiera. Per impartire a screen un comando lo si deve "avvertire" prima. Avvertirlo significa specificare che l'input è per lui e non per il programma che gira nella finestra. Per "avvertire" screen che stiamo per impartirgli un comando si usa la combinazione di tasti ctrl+a **. A questo punto diamo il comando d che sta per "detach", è un poco come mettere in pausa un'intera sessione. Cioè come accontonarla temporanemente. Mentre la sessione è staccata, e noi quindi non stiamo lavorando in nessuna finastra, il nostro mc continua a girare indisturbato; se fosse un wget continuerebbe a scaricare ad esempio. Qui già si possono intuire altre potenzialità di screen.

Ora concentriamoci sulle soket, dovremmo averne una a questo punto. Come faccimao a controllare?
:~$screen -ls
oppure
:~$screen -list
Ci dovrebbe apparire un otput del tipo:
There is a screen on:
4596.pts-0.stellascura (Detached)
1 Socket in /var/run/screen/S-mesillo.
Analiziamo in particolare la seconda riga. Questa descrive la maniera di nominare le soket/sessioni di screen. Dobbiamo leggerla come:
[pid di screen].[terminale a cui è attaccata la sessione].[hostname] ([stato])
Chiariamo alla menopeggio il concetto di attaccato e staccato per una sessione rispetto ad un terminale. Quando una sessione è attaccata ad un terminale vuol dire che una delle sue finestre lo "occuperà". Sò che è riduttivo e in parte inesatto ma per ora vediamola così. Ricordiamoci che un processo (programma) può benissimo continuare a girare anche quando è staccato da un terminale.

Adesso abbiamo la nostra sessione distaccata e vorremmo riattaccarla. Per fare ciò si usa l'opzione -r, che può essere accompagnata da parametro oppure no. Se si usa r senza parametro screen attaccherà al terminale in uso la prima sessione disponibile. Nel nostro caso v'è n'è una solamente quindi ci và più che bene.
:~$screen -r
Se, invece, avessimo più sessioni potremmo usare un comando del tipo:
:-$screen -r 4596.pts-0.stellascura
o se volessimo usare solo il pid della sessione:
:-$screen -r 4596
potremmo, addirittura, specificare solo il nome del terminale. Screen è "intelligente" e, se non forniamo informazioni ambigue (eg.: due sessioni con lo stesso terminale), riesce spesso a capire cosa vogliamo.
A questo punto vedremo riapparire il nostro mc. Chiudiamolo e vedremo un output a shell del tipo:
:~$ screen -r
[screen is terminating]
mesillo@stellascura:~$ screen -list
No Sockets found in /var/run/screen/S-mesillo.

mesillo@stellascura:~$
Il successivo controllo delle soket ci dirà che nessuna sessione è apera.
Vediamo ora come dare un nome alle sessioni per meglio riconoscerle senza doversi ricordare i pid.
:~$screen -S pippo mc
L'opzione in questione è -S con la S maiuscola. Ora distacchiamo la sessione e controlliamo le soket attive. Osserveremo un otput del tipo:
There is a screen on:
8652.pippo (Detached)
1 Socket in /var/run/screen/S-mesillo.
Possiamo riattacare la sessione con:
:~$screen -r pippo
Credo che con molte sessioni attive sia comoda questa possibilità.

Ora è il momento di aggiungere delle nuove finestre alla nostra sessione. Per farlo usiamo il comando interattivo c quindi premiamo ctrl+a e c. Ci apparirà una shell (quella di default *), in una nuova finestra, attraverso la quale possiamo avviare il programma che preferiamo. Per comodità di chi scrive ammettiamo di avviare joe.
Possiamo spostarci da una finestra all'altra con diversi comandi. Tenete conto che screen tratta le finestre come se fossero inserite in una lista. Ogni finestra ha il suo numero. La prima che avete avviato sarà la numero 0, la seconda la numero 1, ecc... . La lista è ciclica, ossia dopo l'ultima finestra si torna alla prima e, di conseguenza, prima della prima c'è l'ultima.
Fatte le dovute premesse ecco la lista dei comandi.
  • n: ci si sposta alla finestra successiva.
  • p: ci si sposta alla finestra precedente.
  • n: (dove n è un numero da 0 a 9) ci si sposta alla finestra numero n.
Quindi, nel nostro esempio: con p torniamo a mc, con n andiamo a joe, con 0 ancora a mc e con 1 a joe di nuovo. Ben s'intende che, essendo questi comandi dinamici, vanno tutti, e sempre, preceduti da ctrl+a.

Chiudere una finestra non è difficile, basta chiudere il programma, o la shell (exit), che essa contiene. Quando chiudiamo l'ultima finestra di una sezione terminiamo anche la sezione stessa ed il suo soket scompare.

Ora sappiamo:
  • Avviare una sezione (con nome anche).
  • Creare delle finestre.
  • Muoverci tra le finestre.
  • Chiudere le finestre e le sessioni.
  • Staccare una sessione.
  • Controllare le sessioni aperte.
  • Attaccare una sessione.
Abbiamo visto solo parte delle funzioni di screen. Ed abbiamo imparato a sfruttarlo solo in maniera base. Infatti screen è uno strumento potente quasi al limite del pericoloso a volte. Parte delle potenzialità di screen si sono certamente intuite fin qui, ma per ora ci accontentiamo del nostro bravo terminale multitasking!

Teniamo sempre a mente che screen altera un poco il comportamento dei programmi. Basti pensare al fatto che si impadronisce della combinazione ctrl+a. Alle volte è anche costretto a modificare, anche se solo in modo temporaneo, l'otput dei programmi per avvisarci di qualcosa. Proprio per ovviare a questi problemi screen prevede l'uso di file di configurazione che, volendo, ne alterano, anche di molto, il comportamento per poterlo adattare alle varie esigenze. Per ora però non vado oltre. Se non resistite alla curiosità non vi resta che dare un man screen.



Utenti Debian etch: potrebbe capitare che sulla vostra distribuzione screen non sia incluso di default... il procedimanto per installarlo è quello canonico!
:~$su
passwd:
:~$apt-get update
:~$apt-get install screen
Non dovrebbe nemmeno chiedervi di risolvere delle dipendenze.

(*)Controllare la shell di default:
:~$echo $SHELL
(**) Dovessimo mai passare al programma nella finestra proprio ctrl+a basterebbe usare ctrl+a e a.

3 commenti:

  1. Sei stato davvero illuminante!!!
    Grazie infinite
    Un unico neo è quello che mi lascia i programmi in esecuzione...
    macchisenefrega!!!

    RispondiElimina
  2. Grazie Mille! Lieto di esserti stato utile!

    RispondiElimina
  3. Ciao, bell'articolo, spiega in modo chiaro come utilizzare screen!

    Fabio

    RispondiElimina