Your Ad Here

Basi di Linux – Variabili d’ambiente

September 21, 2007

Variabili d’ambiente

Penso che ormai tutti voi sanno che cosè una shell: praticamente è il nostro ambiente di lavoro. Adesso cerchiamo di capire che cos’è una sottoshell.

Definizione4: Quando si esegue il login nel proprio account, Linux genera una shell per l’utente. All’interno di questa shell si possono eseguire comandi e dichiarare variabili. Inoltre è possibile creare ed eseguire file script realizzati con i comandi della shell, quindi dei file che raggruppano un insieme di comandi di sistema pronti per essere lanciati in esecuzione (un pò simili se vogliamo ai vecchi file bach dell’MS-DOS). Quando si esegue un file script della shell, il sistema genera una sottoshell. Dunque a questo punto vi sono due shell, quella alla quale si è connessi e quella generata per lo script. All’interno della shell dello script, si potrebbe eseguire un altro script (quindi uno script nidificato all’interno di un’altro script) per il quale verrà attivata una terza shell. Quando uno script termina la propria esecuzione, si conclude anche l’esecuzione della shell relativa e l’utente torna alla shell dalla quale era partito (in sostanza la shell padre). In questo senso si può dire che esistono contemporaneamente più shell, una all’interno dell’altra.
Con un esempio definiamo uno script shell:

[roberto@geelong roberto]$ vi prova.sh
#!/bin/bash

COUNTER=0
clear
while [ $COUNTER = 0 ]; do

tput cup 0 0
echo “ciao”
done

[roberto@geelong roberto]$ chmod +x prova.sh

con questo comando diamo i permessi di esecuzione (x) al file prova.sh (comunque più avanti avremo modo di parlerne). Apriamo un’altro terminale (cliccate sull’icona del terminale in basso a sinistra) e da questo digitiamo:

[roberto@geelong roberto]$ w

3:24pm up 6:11, 5 users, load average: 1.73, 1.92, 1.06
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty1 -9:50am 4:02m 0.40s 0.01s /bin/sh /usr/X1
root pts/0 -11:22am 4:02m 0.00s 0.00s /bin/cat
root pts/1 -11:22am 3:52m 0.08s 0.08s /bin/bash
roberto pts/3 192.168.1.2 3:14pm 0.00s 0.05s 0.01s w
roberto pts/4 192.168.1.2 3:15pm 9.00s 0.02s 0.01s -bash

il comando w ci da un elenco degli utenti collegati al sistema in questo momento. Adesso abbiamo il primo terminale su pts/3 ed il secondo su pts/4. Dall’ultimo terminale aperto mandiamo in esecuzione lo script:

[roberto@geelong roberto]$ ./prova.sh

e vediamo che lo script va in loop. Dal terminale pts/3 digitiamo:

[roberto@geelong roberto]$ ps -ef
UID PID PPID C STIME TTY TIME CMD
….
root 23076 628 0 15:15 ? 00:00:03 in.telnetd: 192.168.1.2
root 23101 23076 0 15:15 pts/4 00:00:00 login — roberto
roberto 24399 23101 0 15:15 pts/4 00:00:00 -bash
roberto 30747 24399 7 15:33 pts/4 00:00:00 /bin/bash ./prova.sh
roberto 1815 30747 0 15:33 pts/4 00:00:00 tput cup 0 0

roberto 1819 18123 0 15:33 pts/3 00:00:00 ps -ef

il comando ps ci da una lista dei processi attivi in questo momento, cioè di tutti i programmi che attualmente sono in funzione nel nostro sistema. La maggior parte di questi programmi gira in background, cioè silenziosamente senza che noi ce ne accorgiamo. Si possono vedere nella prima colonna il nome dell’utente che ha lanciato il processo, poi segue il PID del processo (process ID) cioè quel numero che lo identifica in modo univoco , poi abbiamo il PPID (parent process ID) cioè il PID che l’ha generato, poi seguono altre informazioni come lo start time (STIME) del processo, su quale terminale è in esecuzione (TTY), il tempo di esecuzione (TIME), ed il nome del comando (CMD). Alla linea dove appare il comando “tput cup 0 0″ vediamo che il parent ID di 1815 (prima colonna) è proprio il PID 30747 (seconda colonna) dove è stato lanciato lo script prova.sh. La sottoshell con il PID 1815 (prima colonna) sta
attualmente eseguendo la linea dello script tput cup 0 0. Se in questo momento chiudiamo lo script prova.sh, chiuderemo implicitamente anche la sottoshell generata da questo script, cioè “tput cup 0 0″. Questo vuol dire che se stoppiamo il processo padre, a cadere stopperemo tutti i processi figli.

Definizione5: Le variabili definite all’interno di una shell sono locali all’interno della shell stessa. Le variabili d’ambiente nella shell BASH devono essere esportate, a differenza dalla altre shell. Questo significa che per ogni sottoshell viene creata una copia di una variabile d’ambiente. Con il comando export si richiede al sistema di definire una copia della variabile per tutte le sottoshell generate. Si può pensare che le variabili esportino il proprio valore
in una shell. Per chi conosce le strutture di programmazione, il meccanismo può essere considerato una forma di chiamata per valore.

Per esempio:

[root@diamondhead /home]# PILLO=”ciao”;

non la esportiamo subito, ma lanciamo:

[root@diamondhead /home]# echo $PILLO
ciao

come si vede il valore della variabile viene stampato, ma se cerchiamo di visualizzare questo valore in uno script, generando quindi una sottoshell, il valore non verrà visualizzato:

[root@diamondhead /home]# vi prova.sh
#!/bin/bash

echo $PILLO

[root@diamondhead /home]# chmod 777 prova.sh
[root@diamondhead /home]# ./prova.sh

il 777 dopo il comando chmod è un’altra forma per dare i permessi di esecuzione (anche di questo ne parleremo più avanti). Se vogliamo che questo valore venga visto anche dalle sottoshell dobbiamo esportare la variabile pippo:

[root@diamondhead /home]# export PILLO
[root@diamondhead /home]# ./prova.sh
ciao

Nella shell utente abbiamo diverse variabili d’ambiante già preimpostate. Difatti se lanciamo il comando:

[roberto@diamondhead roberto]$ set

avremo come risposta una serie di variabili d’ambiente preimpostate. Come si vede dall’output ci sono variabili scritte in maiuscolo ed in minuscolo. Quelle in maiuscolo sono dette variabili speciali mentre quelle scritte in minuscolo sono dette variabili locali. Per esempio la variabile speciale HOME definisce il percorso della directory home dell’utente, mentre la variabile locale noclobber,
come già abbiamo visto, impedisce la cancellazione accidentale con un’operazione di redirezione. Alcune delle variabili speciali sono liberamente modificabili, come ad esempio la variabile PATH, altre invece è meglio non farlo, come la variabile HOME.
Per ottenere un elenco delle variabili speciali attualmente definite si
può usare il comando env:

[roberto@geelong roberto]$ env

env si comporta come il comando set ma elenca solo le variabili speciali. Per definire automaticamente tutte le variabili speciali esiste il file .bash_profile posto nella directory dell’utente:

[roberto@diamondhead roberto]$ more .bash_profile

non appena si esegue il login nel sistema, tramite shell, la prima cosa che il sistema fa è quella di leggere il contenuto di questo file per il nostro utente. Nella shell BASH, abbiamo detto, per trasformare una variabile normale in una d’ambiente dobbiamo esportarla con il comando export. Come si può notare, al termine del file .bash_profile vengono esportate le variabili definite nello script, cioè le variabili BASH_ENV e PATH. Proviamo ora a visualizzare con il comando echo alcune di queste variabili:

[roberto@diamondhead roberto]$ echo $HOME
/home/roberto

viene visualizzato il percorso della home del nostro utente.
Proviamo ora con:

[roberto@diamondhead roberto]$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/roberto/bin

abbiamo i vari percorsi relativi ai comandi di sistema. Proviamo adesso a creare una directory personale dove mettere tutti i nostri script eseguibili. Possiamo creare questa directory con il nome myscript. Al posto di specificare per esteso
/home/roberto/myscript, si può utilizzare la variabile speciale HOME in questo modo:

[roberto@diamondhead roberto]$ vi .bash_profile
PATH=$PATH:$HOME/myscript
export PATH

usciamo dalla shell e rientriamo. (questo comporta l’uscita da VNC!, si potrebbe usare source .bash_profile).

Se facciamo un:

[roberto@diamondhead roberto]$ echo $PATH

vedremo effettivamente che nel PATH c’è la nostra directory myscript dove potremo mettere i nostri script personali. Per fare in modo che nel PATH ci sia anche la directory di lavoro attuale, per eseguire direttamente dove ci troviamo degli script o comunque degli eseguibili, possiamo aggiungere alla variabile PATH un “:” in questo modo:

[roberto@diamondhead roberto]$ vi .bash_profile
PATH=$PATH:$HOME/myscript:

il “:” finale sta ad indicare che si deve prendere in considerazione, per la ricerca degli eseguibili, anche la directory attuale di lavoro.
Proviamo a create un file script:

[roberto@diamondhead roberto]$ vi pippo.sh
#!/bin/bash

ls -la

[roberto@diamondhead roberto]$ chmod 777 pippo.sh
[roberto@diamondhead roberto]$ pippo.sh
[roberto@diamondhead roberto]$ source .bash_profile

Adesso proviamo a lanciare pippo.sh:

[roberto@diamondhead roberto]$ pippo.sh

noteremo che lo script pippo.sh verrà eseguito dalla directory corrente. Se vogliamo trasferire lo script pippo.sh all’interno della directory che abbiamo creato, cioè “myscript”. Possiamo fare un:

[roberto@diamondhead roberto]$ mv pippo.sh myscript/
[roberto@diamondhead roberto]$ ls myscript/

Ora proviamo dalla nostra home directory a lanciare pippo.sh senza specificare il percorso dove si trova:

[roberto@diamondhead roberto]$ pippo.sh

Lo script verrà trovato grazie alla variabile PATH e dunque lanciato.
Adesso proviamo a visualizzare il contenuto di PS1 e PS2:

[roberto@diamondhead roberto]$ echo $PS1
[\u@\h \W]\$
[roberto@diamondhead roberto]$ echo $PS2
>

La variabile PS1 contiene il valore del prompt del sistema, mentre PS2 contiene il prompt secondario, cioè il simbolo che appare quando il comando viene completato su più righe.

Si possono mettere informazioni particolari come ora, data, nome utente, etc.

Definizione6: Il file .bash_profile è lo script di inizializzazione della shell e viene eseguito automaticamente al momento del login dell’utente. Mentre .bash_profile inizializza la shell dell’utente, c’è un’altro file all’interno della directory /etc che si chiama profile. (andiamo a vedere un attimo: more /etc/profile). In questo script vengono inizializzate le variabili di sistema ancora prima che lo script .bash_profile del relativo utente viene mandato in esecuzione.

Per verificare questo possiamo definire la stessa variabile con valori diversi nei due file /etc/profile e /$HOME/.bash_profile esportandola correttamente e vedere con un echo quale dei due valori viene stampato. Siete in grado di verificarlo da soli? (ricordare che per leggere le nuove variabili definite bisogna lanciare:

source nome_file – es: source /etc/profile)

Definizione7: Lo script .bashrc è un file che si trova nella directory di ogni utente e che viene eseguito anch’esso ogni volta che si accede alla shell o ad una sottoshell. Se si utilizza la shell BASH come shell di login, il file .bashrc viene eseguito subito dopo il file .bash_profile durante la procedura di login. Se la shell di default fosse stata la TCSH il file eseguito sarebbe stato .tcshrc.

Leave a Reply