[ precedente ] [ Contenuti ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ 13 ] [ 14 ] [ 15 ] [ 16 ] [ 17 ] [ 18 ] [ 19 ] [ A ] [ B ] [ C ] [ D ] [ successivo ]


Debian Tutorial
Capitolo 6 - Usare la shell


6.1 Variabili d'ambiente

Ogni processo ha un ambiente ad esso associato. Un ambiente è una raccolta di variabili di ambiente. Una variabile è un valore modificabile con un nome fisso. Per esempio, il nome EMAIL potrebbe fare riferimento al valore joe@nowhere.com. Il valore può cambiare: EMAIL potrebbe anche fare riferimento a jane@somewhere.com.

Poiché la propria shell è un processo come ogni altro, ha un ambiente. Si può vedere il proprio ambiente della shell digitando il comando printenv. Ecco un output di esempio:

     PAGER=less
     HOSTNAME=icon
     MAILCHECK=60
     MOZILLA_HOME=/usr/local/lib/netscape
     PS1=$ 
     USER=hp
     MACHTYPE=i486-pc-linux-gnu
     EDITOR=jed
     DISPLAY=:0.0
     LOGNAME=hp
     EMAIL=hp@pobox.com
     SHELL=/bin/bash
     HOSTTYPE=i486
     OSTYPE=linux-gnu
     HISTSIZE=150
     HOME=/home/hp
     TERM=xterm-debian
     TEXEDIT=jed
     PATH=/home/hp/local/bin:/usr/sbin:/home/hp/.bin:/home/hp/local/bin:/usr/sbin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:.
     _=/usr/bin/printenv

Sul proprio sistema, l'output potrà essere differente, ma similare.

Le variabili di ambiente sono un modo per configurare il sistema. Per esempio, la variabile EDITOR permette di selezionare il proprio editor preferito per le news, per scrivere e-mail e così via. La variabile HISTSIZE indica alla Bash quante righe di comando deve memorizzare nella sua cronologia; si può ritornare a tutte queste righe di comando con il tasto "freccia su".

Impostare le variabili di ambiente è semplice. Una volta che si è imparato come fare, probabilmente si vorrà impostarle automaticamente ogni volta che si fa il login; vedere Personalizzare la shell, Capitolo 9 per le istruzioni.

Per fare pratica, si provi a personalizzare il prompt della propria shell e il proprio visualizzatore dei file di testo, utilizzando le variabili di ambiente:

  1. man less

    Visualizzare la pagina di manuale del comando less. Al fine di mostrare il testo una schermata alla volta, man richiama un paginatore che mostra una nuova pagina di testo ogni volta che si preme la barra spaziatrice. In modo predefinito utilizza il paginatore chiamato more.

    Continuare e dare uno sguardo alla pagina di manuale di less, che è un paginatore evoluto. Premere la barra spaziatrice per scorrere a una nuova pagina; premere q per uscire. more esce anche automaticamente quando si raggiunge la fine della pagina di manuale.

  1. export PAGER=less

    Dopo avere letto dei vantaggi di less, si potrebbe volerlo utilizzare per leggere le pagine di manuale. Per fare questo, impostare la variabile di ambiente PAGER.

    Il comando per impostare una variabile di ambiente all'interno di bash, ha sempre questo formato: export NOME=valore. Se capita di usare tcsh o un altro derivato della shell C, il comando equivalente è setenv NOME valore.

    export significa spostare la variabile dalla shell dentro all'ambiente. Significa che anche gli altri programmi oltre alla shell stessa potranno utilizzarla.

  1. echo $PAGER

    Questo è il modo più semplice per vedere il valore di una variabile. $PAGER indica alla shell di inserire il valore della variabile PAGER prima di invocare il comando. echo ritorna il suo argomento: in questo caso echo ritorna il valore attuale di PAGER, less.

  1. man more

    Leggere il manuale di more. Questa volta, man dovrebbe avere richiamato il paginatore less.

    less ha molte caratteristiche che mancano a more. Per esempio si può scorrere indietro con il tasto b. È anche possibile muoversi su e giù (e anche lateralmente) con i tasti freccia. less non esce quando si raggiunge la fine della pagina di manuale; aspetta che si prema il tasto q.

  1. PAGER=more man more

    Se si vuole un'impostazione temporanea differente, si può mettere un nuovo valore che avrà effetto solo sulla riga di comando attuale. Mettere NOME=valore all'inizio della riga di comando, seguito dal comando da eseguire. Assicurarsi di omettere export.

    Si possono provare alcuni comandi specifici di less, tipo b, per verificare che non funzionano con more e che effettivamente si sta utilizzando more.

  1. echo $PAGER

    Il valore di PAGER dovrebbe essere ancora less; l'impostazione suddetta era solo temporanea.

  1. unset PAGER

    Se non si vuole più specificare un paginatore, si può disimpostare la variabile con unset. man userà allora more in modo predefinito, proprio come faceva prima che si impostasse la variabile.

  1. echo $PAGER

    Siccome PAGER è stato disimpostato, echo non mostrerà niente.

  1. PS1=hello:

    Solo per divertimento, cambiare il prompt di shell. $ dovrebbe trasformarsi in hello:.

    export non è necessario, perché si sta modificando il comportamento della shell stessa. Non ci sono ragioni per esportare la variabile nell'ambiente per essere vista da altri programmi. Tecnicamente, PS1 è una variabile di shell piuttosto che una variabile di ambiente.

    Volendo si può usare export sulla variabile di shell, trasformandola in una variabile di ambiente. Allora altri programmi potranno vederla: in modo particolare, i processi figli dell'attuale processo shell. La prossima sezione spiega questo.


6.1.1 Processi genitori e figli

Tutti i processi derivano da un processo precedente, chiamato il loro processo genitore. [10] Il comando ps è uno strumento utile per l'esplorazione dei processi e può essere utilizzato per esaminare le relazioni genitore-figlio.

  1. ps f

    Questo comando richiede di vedere una lista di processi che ci appartengono, in un formato che mostra come i processi sono correlati.

ps f potrebbe generare un output simile a questo:

     $ ps f
       PID  TT STAT   TIME
      7270  p5 S      0:00 bash
     15980  p5 R      0:00  \_ ps f
     19682  p4 S      0:00 bash
     15973  p4 S      0:00  \_ man ps
     15976  p4 S      0:00      \_ sh -c /bin/gzip -dc '/var/catman/cat1/ps.1.gz' | { export MAN_PN LESS; MAN_PN='ps(1)'; LESS="$LESS\$-Pm\:\$i
     15977  p4 S      0:00          \_ /bin/gzip -dc /var/catman/cat1/ps.1.gz
     15978  p4 S      0:00          \_ sh -c /bin/gzip -dc '/var/catman/cat1/ps.1.gz' | { export MAN_PN LESS; MAN_PN='ps(1)'; LESS="$LESS\$-Pm\
     15979  p4 S      0:00              \_ less
     $

Qui si può vedere che si hanno un certo numero di processi in esecuzione, incluse due shell. Le shell hanno dei processi figli: il processo shell 7270 ha il processo figlio 15980 (ps f) e la shell 19682 ha il processo figlio 15973 (man ps). man ps ha a sua volta richiamato una serie complessa di sottoprocessi al fine di mostrare una pagina di manuale. Per adesso non ci si preoccupi di cosa facciano questi sottoprocessi.

Genitori e figli hanno delle relazioni complesse. Il più delle volte, quando un processo genitore termina, così fa anche quello figlio. Così si può uccidere un intero insieme di processi, per esempio tutti i figli di man ps nell'esempio sopra, uccidendo il processo genitore, 15973.

I processi figli ereditano le variabili di ambiente dei loro genitori e alcuni altri attributi, come la directory di lavoro attuale.

Quando una shell esegue un comando, avvia il comando come un processo figlio. Così il comando man eredita l'ambiente di shell; se si è impostata la variabile PAGER, man potrà vederla.

Se fallisce il tentativo di fare l'export di una variabile, solo la shell stessa la vedrà e non sarà passata ai processi figli come man.


6.2 Dove "abitano" i comandi: la variabile PATH

Quando si digita un comando nella shell, essa deve trovare il programma sull'hard disk prima di eseguirlo. Se la shell dovesse cercarlo su tutto il disco, sarebbe molto lenta; invece, cerca in una lista di directory contenuta nella variabile di ambiente PATH. Questa lista di directory costituisce il percorso di ricerca della shell; quando si introduce un comando, la shell guarderà a turno ognuna di esse alla ricerca del programma che si è chiesto di avviare.

Potrebbe essere necessario modificare la variabile PATH se si installano da soli programmi in posizioni non standard.

Il valore della variabile PATH è una lista di directory separate dal carattere ":". Il valore predefinito sui sistemi Debian è:

     /usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Questo valore è definito nel file /etc/profile e viene applicato a tutti gli utenti. Si può cambiare facilmente il valore, proprio come si può modificare ogni altra variabile di ambiente.

Se si da il comando ls, la shell prima cercherà in /usr/local/bin; se ls non è là, allora proverà /usr/bin; quando questo fallisce, proverà /bin. Là troverà /bin/ls, fermerà la sua ricerca ed eseguirà il programma /bin/ls. Se esistesse /usr/bin/X11/ls (non esiste, ma supponiamolo), esso sarebbe ignorato.

Si può vedere quale ls la shell userà con il comando type. type ls risponderà /bin/ls; lo si provi.

Provare chiedendo dove type stesso si trovi:

     $ type type
     type is a shell builtin

type non è di fatto un programma; è una funzione implementata dalla shell. Ciò nonostante, lo si usa proprio come un programma esterno. [11]

Ci sono numerosi comandi simili a questo; si digiti man builtins per leggere le pagine di manuale che li descrivono. In generale non si ha bisogno di sapere se un comando è un comando interno o un vero programma; comunque, i comandi interni non saranno mostrati nell'output di ps o top dato che non sono processi separati. Essi sono solo parte della shell.


6.3 Alias e funzioni della shell

Se si usa spesso lo stesso comando, ci si potrebbe stancare di digitarlo. bash permette di scrivere degli alias più brevi per i propri comandi. Si possono anche scrivere delle funzioni di shell, che sono comandi personalizzati composti da numerosi altri comandi.

Se per esempio si usano spesso le opzioni --almost-all e --color=auto del comando ls, ci si può stancare presto di digitare ls --almost-all --color=auto. Così si può creare un alias:

     alias miols='ls --almost-all --color=auto'

Adesso si può digitare miols invece del comando completo. Per vedere cosa sia realmente miols, si dia il comando type miols. Per vedere una lista degli alias che sono stati definiti, si digiti semplicemente alias da solo.

Le funzioni di shell sono un po' più flessibili degli alias. Un alias semplicemente sostituisce un comando più lungo quando se ne digita uno più corto. Le funzioni permettono di usare una serie di comandi per compiere alcune operazioni.

Per prima cosa vediamo come una funzione di shell può essere utilizzata al posto dell'alias visto sopra:

     miols() {
         ls --almost-all --color=auto $*
     }

Quella sopra è chiamata definizione di funzione, perché fornisce un nome di funzione (miols), quindi definisce il significato del nome (alcuni comandi da eseguire). Per definire una funzione, si scriva il suo nome, seguito da (). Poi si includano i comandi da eseguire tra parentesi graffe ({}). La porzione tra le parentesi graffe è detta corpo della funzione.

Ci si può riferire agli argomenti per la funzione come $*. Così se si digita:

     miols /usr  /etc

$* sarà /usr /etc, i due argomenti. Se non ci sono argomenti, $* sarà vuoto.

Ci si può riferire agli argomenti anche tramite numeri. Così $1 nel corpo della funzione verrebbe sostituito da /usr e $2 verrebbe sostituito da /etc. Digitare questa funzione (si può scriverla sul prompt della shell; premere Invio dopo ciascuna riga):

     stampa_argomenti() {
         echo "Primo argomento:   $1"
         echo "Secondo argomento:  $2"
         echo "Argomenti completi:    $*"
     }

Si può verificare di avere introdotto la definizione di funzione correttamente con il comando type; type stampa_argomenti restituirà:

     stampa_argomenti is a function
     stampa_argomenti () 
     { 
         echo "Primo argomento:   $1";
         echo "Secondo argomento:  $2";
         echo "Argomenti completi:    $*"
     }

Provare la funzione. Se si digita stampa_argomenti uno due verrà mostrato:

     Primo argomento:   uno
     Secondo argomento:  due
     Argomenti completi:    uno due

Ci sono molte cose più complesse che si possono fare con una funzione di shell; si è limitati solo dalla propria immaginazione. Per ulteriori informazioni vedere Introduzione allo scripting di shell, Sezione 17.1.


6.4 Controllare input e output

Stdin, stdout, pipeline e redirezione

Ogni processo possiede almeno tre collegamenti con il mondo esterno. Lo standard input è una delle sorgenti dei dati del processo; lo standard output è il posto dove il processo invia i dati; e lo standard error è il posto dove il processo può inviare i messaggi di errore. (Sono sovente abbreviati come stdin, stdout e stderr.)

Le parole `sorgente' e `posto' sono intenzionalmente generiche. Queste posizioni di standard input e standard ouput possono essere cambiate dall'utente; possono essere lo schermo, la tastiera, un file, persino una connessione di rete. L'utente può specificare quale posizione usare.

Quando si avvia un programma dalla shell, solitamente lo standard input proviene dalla tastiera ed entrambi lo standard output e lo standard error confluiscono sullo schermo. Comunque, si può chiedere alla shell di modificare questi comportamenti predefiniti.

Per esempio, il comando echo invia il suo output sullo standard output, solitamente lo schermo. Ma si può invece inviarlo su un file con l'operatore di redirezione dell'output, '>'. Per esempio, per mettere la parola "Hello" nel file miofile:

     echo Hello > miofile

Si utilizzi cat o il paginatore di file di testo (more o less) per vedere il contenuto di miofile.

Si può modificare lo standard input di un comando con l'operatore di redirezione dell'input, '<'. Per esempio, more < miofile mostrerà il contenuto di miofile. In pratica non è utile; per comodità, il comando more accetta un nome di file come argomento. Così si può dire semplicemente more miofile e il risultato sarà lo stesso.

In definitiva, more < miofile significa che la shell apre miofile, poi invia il suo contenuto sullo standard input di more. more miofile, senza l'operatore di redirezione, significa che il comando more riceve un argomento, miofile, apre il file e poi mostra il file.

Tuttavia c'è una ragione a questa doppia funzionalità. Per esempio, si può collegare lo standard output di un comando con lo standard input di un altro. Questa cosa è chiamata pipeline e utilizza l'operatore di pipe, '|'.

Forse si vuole vedere la GNU General Public License al contrario. Per farlo, si usi il comando taccat, solo al contrario). Provare:

     tac /usr/doc/copyright/GPL

Sfortunatamente, va troppo veloce per riuscire a leggerlo. Così si riusciranno a vedere solo un paio di capoversi. La soluzione è una pipeline:

     tac /usr/doc/copyright/GPL | more

Questo comando prende lo standard output di tac, che è la GPL al contrario e lo invia sullo standard input di more.

Si possono concatenare tanti comandi quanti si vuole. Immaginiamo si abbia un inspiegabile desiderio di sostituire ogni G con Q; per fare questo si usa il comando tr G Q, così:

     tac /usr/doc/copyright/GPL | tr G Q | more

Si può ottenere la stessa cosa utilizzando i file temporanei e la redirezione: Per esempio:

     tac /usr/doc/copyright/GPL > tmpfile
     tr G Q < tmpfile > tmpfile2
     more < tmpfile2
     rm tmpfile tmpfile2

Ovviamente una pipeline è più conveniente.


6.5 Specificare come e quando avviare i comandi

"modificatori" tipo batch, at, nohup, nice


6.6 Espansione dei nomi di file ("Metacaratteri")

Spesso si desidera che un comando operi su un gruppo di file. I "metacaratteri" (wildcard) sono utilizzati per creare un modello di espansione dei nomi di file: una serie di caratteri e metacaratteri che si espande in una lista di nomi di file. Per esempio, il modello /etc/* si espande in una lista di tutti i file in /etc [12]. * è un metacarattere che può significare una qualsiasi serie di caratteri, così il modello /etc/* si espanderà in una lista di tutti i nomi di file che iniziano con /etc/.

Questa lista di nomi di file è molto utile come insieme di argomenti per un comando. Per esempio, la directory /etc contiene una serie di sottodirectory chiamate rc0.d, rc1.d, ecc. Normalmente, per vedere il contenuto di queste directory, si digiterebbe:

     ls /etc/rc0.d /etc/rc1.d /etc/rc2.d /etc/rc3.d /etc/rc4.d /etc/rc5.d /etc/rc6.d /etc/rcS.d

Ciò è noioso. Al suo posto si può usare il metacarattere ?:

     ls /etc/rc?.d

/etc/rc?.d si espande in una lista di nomi di file che iniziano con rc, seguito da un qualsiasi singolo carattere che precede .d.

I metacaratteri disponibili sono:

*

Corrisponde a qualsiasi gruppo di zero o più caratteri

?

Corrisponde ad esattamente un carattere

[...]

Se si chiudono alcuni caratteri tra parentesi quadre, il risultato è un metacarattere che corrisponde a questi caratteri. Per esempio, [abc] corrisponde ad a, b, o c. Se si aggiunge un ^ dopo la prima parentesi quadra, il significato viene invertito; così [^abc] corrisponde ad ogni carattere che non sia a, b, o c. Si può inserire un intervallo, tipo [a-j], che corrisponde a qualsiasi cosa tra a e j. La corrispondenza è sensibile alle minuscole/maiuscole, cosicché per indicare ogni lettera, si deve usare [a-zA-Z].

I modelli di espansione sono semplici, una volta che si siano visti alcuni esempi concreti:

*.txt

Questo fornisce una lista di ogni nome di file che finisce in .txt, dato che * corrisponde ad ogni cosa.

*.[hc]

Questo fornisce una lista di nomi di file che terminano in .h o .c.

a??

Questo fornisce tutti i nomi di file di tre lettere che iniziano con a.

[^a]??

Questo fornisce tutti i nomi di file di tre lettere che non iniziano con a.

a*

Questo fornisce tutti i nomi di file che iniziano con a, indipendentemente dal numero di lettere che contengono.


6.7 Interattiva/non-interattiva

Bash possiede due modalità differenti: interattiva e non-interattiva. Interattiva significa che si può digitare verso di essa e che essa farà cose per conto nostro. Le shell non-interattive interpretano script di shell, in modo simile ai file batch del DOS. Viene fornito alla shell un elenco di comandi da svolgere ed essa lo fa, ma senza intervento dell'utente. Non si vedranno tutti i comandi digitati. Naturalmente ogni output sarà registrato da qualche parte (lo standard output, o stdout, normalmente sullo schermo o su un file di log). Vedremo di più sulle shell non-interattive tra poco.


6.7.1 Shell interattive

Le shell interattive richiederanno molto tempo per imparare a padroneggiarle, solo perché sono così potenti: probabilmente non si imparerà mai ogni cosa! C'è così tanto che una shell può fare e naturalmente è in continuo cambiamento. Qui parleremo della bash e di alcuni comandi di base che renderanno più facile la propria vita con la shell. Nella bash, si possono fare contemporaneamente molte cose, e questo può confondere.

Una shell è un ambiente Line Oriented o a riga di comando. La shell si interfaccerà sempre mediante un prompt, ogni volta che è in attesa che si faccia qualcosa. Il prompt predefinito in Debian è un $. Il prompt $ è dove si digitano comandi per comunicare a Linux di fare qualcosa; può essere un nome di programma o può essere un comando "interno" che la shell fornisce per comodità.


[ precedente ] [ Contenuti ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ 13 ] [ 14 ] [ 15 ] [ 16 ] [ 17 ] [ 18 ] [ 19 ] [ A ] [ B ] [ C ] [ D ] [ successivo ]


Debian Tutorial

30 settembre 2007

Havoc Pennington hp@debian.org