1703 lines
No EOL
56 KiB
Text
1703 lines
No EOL
56 KiB
Text
<!--
|
|
The FreeBSD Italian Documentation Project
|
|
|
|
$FreeBSD$
|
|
-->
|
|
|
|
<chapter id="shell-programming">
|
|
<title>Programmazione di shell</title>
|
|
|
|
<sect1 id="shell-programming-scripts">
|
|
<title>Script di shell</title>
|
|
|
|
<para>Si possono scrivere programmi di shell creando script contenenti
|
|
alcuni comandi di shell. La prima linea dello script deve iniziare con
|
|
#!, che indica al kernel che lo script è direttamente eseguibile.
|
|
Si fa immediatamente seguire a quel simbolo il nome della shell
|
|
o del programma da eseguire (gli spazi sono permessi), usando un path name
|
|
assoluto. Generalmente si possono avere fino a 32 caratteri, forse di
|
|
più su alcuni sistemi e si può includere qualche opzione.
|
|
Quindi per inizializzare uno script per la shell Bourne la prima linea
|
|
dovrà essere:</para>
|
|
|
|
<programlisting>#! /bin/sh</programlisting>
|
|
|
|
<para>e per la shell C:</para>
|
|
|
|
<programlisting>#! /bin/csh -f</programlisting>
|
|
|
|
<para>dove l'opzione <option>-f</option> indica che la shell non deve
|
|
leggere il file <filename>.cshrc</filename>. Alcuni spazi bianchi
|
|
seguenti il magico simbolo, #!, sono opzionali.</para>
|
|
|
|
<para>Inoltre si deve specificare che lo script è eseguibile,
|
|
settando gli opportuni bit sul file con il comando &man.chmod.1;,
|
|
esempio:</para>
|
|
|
|
<screen>&prompt.user; <userinput>chmod +x <replaceable>shell_script</replaceable></userinput></screen>
|
|
|
|
<para>All'interno degli script il simbolo # indica un commento da quel punto
|
|
fino alle fine della linea; #! è un caso speciale se trovato come
|
|
primo carattere del file.</para>
|
|
</sect1>
|
|
|
|
<sect1 id="shell-programming-sett-param-val">
|
|
<title>Settare i valori dei parametri</title>
|
|
|
|
<para>I valori di un parametro, ad esempio <literal>param</literal>, sono
|
|
assegnati così:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="1.5in">
|
|
|
|
<thead>
|
|
<row>
|
|
<entry>Shell Bourne</entry>
|
|
|
|
<entry>Shell C</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><command>param=<replaceable>valore</replaceable></command></entry>
|
|
|
|
<entry><command>set param =
|
|
<replaceable>valore</replaceable></command></entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>dove <replaceable>valore</replaceable> è una valida stringa che
|
|
può essere chiusa tra caratteri di quoting singoli
|
|
('<replaceable>valore</replaceable>') o doppi
|
|
("<replaceable>valore</replaceable>") per permettere alcuni spazi bianchi
|
|
all'interno del valore della stringa. Quando viene racchiusa con dei
|
|
caratteri backquote (`<replaceable>valore</replaceable>`) la stringa viene
|
|
prima valutata dalla shell e viene sostituita con il risultato ottenuto
|
|
dalla valutazione. Questo viene spesso usato per eseguire un comando,
|
|
sostituendo l'output del comando a <replaceable>valore</replaceable>,
|
|
esempio:</para>
|
|
|
|
<screen>$ <userinput>day=`date +%a`</userinput></screen>
|
|
|
|
<screen>$ <userinput>echo $day</userinput>
|
|
Wed</screen>
|
|
|
|
<para>Dopo che il valore del parametro è stato assegnato, si accede
|
|
al valore corrente del parametro usando la notazione
|
|
<literal>$param</literal> o <literal>${param}</literal>.</para>
|
|
</sect1>
|
|
|
|
<sect1 id="shell-programming-quoting">
|
|
<title>Quoting</title>
|
|
|
|
<para>Le stringhe possono essere quotate per controllare il modo in cui la
|
|
shell interpreta alcuni parametri o variabili all'interno della stringa.
|
|
Per delimitare le stringhe si possono usare i caratteri di quoting singoli
|
|
(') o doppi ("). I caratteri di quoting doppi definiscono la stringa e
|
|
permettono la sostituzione di variabile. I carattere di quoting singoli
|
|
definiscono la stringa ma impediscono la sostituzione di variabile.
|
|
Un backslash (\) prima di un carattere viene posto per effettuare un
|
|
escape su di esso, specificando che il sistema deve considerare il
|
|
carattere letteralmente, senza assegnarli alcun significato speciale.
|
|
Queste tecniche di quoting possono essere usate per separare una variabile
|
|
da una stringa fissa. Come esempio si consideri la variabile
|
|
<literal>var</literal>, a cui è stata assegnata il valore
|
|
<literal>bat</literal>, e la stringa costante <literal>man</literal>. Se
|
|
si vuole combinare queste stringhe per ottenere come risultato la stringa
|
|
<literal>batman</literal> si può sperimentare:</para>
|
|
|
|
<para><literal>$varman</literal></para>
|
|
|
|
<para>ma questo non funzionerà, poichè la shell tenta di
|
|
valutare una variabile chiamata <literal>varman</literal>, che non esiste.
|
|
Per ottenere il risultato desiderato si ha la necessità di separare
|
|
le stringhe tramite quoting o di isolare la variabile con delle parentesi
|
|
graffe ({}), in questo modo:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="1.5in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><literal>"$var"man</literal></entry>
|
|
|
|
<entry>- quoting sulla variabile</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$var""man</literal></entry>
|
|
|
|
<entry>- separazione di parametri</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$var"man"</literal></entry>
|
|
|
|
<entry>- quoting sulla costante</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$var''man</literal></entry>
|
|
|
|
<entry>- separazione di parametri</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$var'man'</literal></entry>
|
|
|
|
<entry>- quoting sulla costante</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$var\man</literal></entry>
|
|
|
|
<entry>- separazione di parametri</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>${var}man</literal></entry>
|
|
|
|
<entry>- si isola la variabile</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>Queste funzionano tutte poichè ", ', \, { e } non sono validi
|
|
caratteri per un nome di variabile.</para>
|
|
|
|
<para>Non si può usare</para>
|
|
|
|
<para><literal>'$var'man</literal></para>
|
|
|
|
<para><literal>\$varman</literal></para>
|
|
|
|
<para>poichè impediscono che la sostituzione della variabile
|
|
prenda posto.</para>
|
|
|
|
<para>Quando si usano le parentesi graffe, queste devono circondare
|
|
solamente la variabile, senza includere il $, altrimenti saranno incluse
|
|
come parte del risultato della stringa, esempio:</para>
|
|
|
|
<screen>&prompt.user; <userinput>echo {$var}man</userinput>
|
|
{bat}man</screen>
|
|
</sect1>
|
|
|
|
<sect1 id="shell-programming-var">
|
|
<title>Variabili</title>
|
|
|
|
<para>Alcune variabili sono automaticamente inizializzate all'avvio della
|
|
shell. Queste variabili permettono di riferirsi agli argomenti su linea
|
|
di comando.</para>
|
|
|
|
<para>Queste <emphasis>variabili di shell</emphasis> sono:</para>
|
|
|
|
<table frame=all id="shell-programming-table-shell-var">
|
|
<title>Variabili di shell</title>
|
|
|
|
<tgroup cols="4">
|
|
<colspec colwidth="1in">
|
|
|
|
<colspec colwidth="5in">
|
|
|
|
<colspec colwidth="0.3in">
|
|
|
|
<colspec colwidth="0.3in">
|
|
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Variabile</entry>
|
|
|
|
<entry align="center">Uso</entry>
|
|
|
|
<entry align="center">sh</entry>
|
|
|
|
<entry align="center">csh</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><literal>$#</literal></entry>
|
|
|
|
<entry>numero di argomenti su linea di comando</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
|
|
<entry align="center"></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$-</literal></entry>
|
|
|
|
<entry>opzioni fornite alla shell</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
|
|
<entry align="center"></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$?</literal></entry>
|
|
|
|
<entry>valore di uscita dell'ultimo comando eseguito</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
|
|
<entry align="center"></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$$</literal></entry>
|
|
|
|
<entry>numero id del processo corrente</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$!</literal></entry>
|
|
|
|
<entry>numero di processo dell'ultimo comando messo in
|
|
background</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
|
|
<entry align="center"></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$<replaceable>n</replaceable></literal></entry>
|
|
|
|
<entry>argomento su linea di comando, dove
|
|
<replaceable>n</replaceable> varia tra 1 e 9, leggendo da sinistra
|
|
a destra</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$0</literal></entry>
|
|
|
|
<entry>il nome della shell corrente o del programma corrente</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$*</literal></entry>
|
|
|
|
<entry>tutti gli argomenti su linea di comando ("$1 $2 ...
|
|
$9")</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$@</literal></entry>
|
|
|
|
<entry>tutti gli argomenti su linea di comando, ciascuno quotato
|
|
separatamente ("$1" "$2" ... "$9")</entry>
|
|
|
|
<entry align="center">x</entry>
|
|
|
|
<entry align="center"></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$argv[<replaceable>n</replaceable>]</literal></entry>
|
|
|
|
<entry>seleziona l'<replaceable>n-esima</replaceable> parola dalla
|
|
lista di input</entry>
|
|
|
|
<entry align="center"></entry>
|
|
|
|
<entry align="center">x</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>${argv[<replaceable>n</replaceable>]}</literal></entry>
|
|
|
|
<entry>come sopra</entry>
|
|
|
|
<entry align="center"></entry>
|
|
|
|
<entry align="center">x</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$#argv</literal></entry>
|
|
|
|
<entry>riporta il numero di parole della lista di input</entry>
|
|
|
|
<entry align="center"></entry>
|
|
|
|
<entry align="center">x</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
|
|
<para>L'uso di queste variabili può essere illustrato con alcuni
|
|
semplici script. Per la shell Bourne lo script potrebbe essere:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
echo "$#:" $#
|
|
echo '$#:' $#
|
|
echo '$-:' $-
|
|
echo '$?:' $?
|
|
echo '$$:' $$
|
|
echo '$!:' $!
|
|
echo '$3:' $3
|
|
echo '$0:' $0
|
|
echo '$*:' $*
|
|
echo '$@:' $@</programlisting>
|
|
|
|
<para>Quando viene eseguito con alcuni argomenti, mostra i valori delle
|
|
variabili di shell, esempio:</para>
|
|
|
|
<screen>$ <userinput>./variables.sh one two three four five</userinput>
|
|
5: 5
|
|
$#: 5
|
|
$-:
|
|
$?: 0
|
|
$$: 12417
|
|
$!:
|
|
$3: three
|
|
$0: ./variables.sh
|
|
$*: one two three four five
|
|
$@: one two three four five</screen>
|
|
|
|
<para>Come si può notare, si ha la necessità di usare un
|
|
carattere di quoting singolo per impedire alla shell di assegnare
|
|
significati speciali a $. Il carattere di quoting doppio, come nella
|
|
prima struttura <command>echo</command>, permette di rimpiazzare il nome
|
|
della variabile con il suo valore.</para>
|
|
|
|
<para>Similmente, per le variabili della shell C si possono illustrare le
|
|
sostituzioni di variabili tramite il seguente script:</para>
|
|
|
|
<programlisting>#!/bin/csh -f
|
|
echo '$$:' $$
|
|
echo '$3:' $3
|
|
echo '$0:' $0
|
|
echo '$*:' $*
|
|
echo '$argv[2]:' $argv[2]
|
|
echo '${argv[4]}:' ${argv[4]}
|
|
echo '$#argv:' $#argv</programlisting>
|
|
|
|
<para>che quando eseguito con alcuni argomenti mostra il risultato
|
|
seguente:</para>
|
|
|
|
<screen>&prompt.user; <userinput>./variables.csh one two three four five
|
|
</userinput>
|
|
$$: 12419
|
|
$3: three
|
|
$0: ./variables.csh
|
|
$*: one two three four five
|
|
$argv[2]: two
|
|
${argv[4]}: four
|
|
$#argv: 5</screen>
|
|
</sect1>
|
|
|
|
<sect1 id="shell-programming-param-sost">
|
|
<title>Sostituzione di parametri</title>
|
|
|
|
<para>Si può riferirsi ai parametri in modo astratto e sostituire i
|
|
loro valori in base a delle condizioni, usando gli operatori definiti qui
|
|
sotto. Ancora una volta si possono usare le parentesi graffe ({}) per
|
|
isolare la variabile e il suo operatore.</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="2in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><literal>$<replaceable>parametro</replaceable></literal></entry>
|
|
|
|
<entry>sostituisce questa stringa con il valore di
|
|
<replaceable>parametro</replaceable></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>${<replaceable>parametro</replaceable>}</literal></entry>
|
|
|
|
<entry>come sopra. Le parentesi sono d'aiuto se non c'è
|
|
separazione tra questo parametro e una stringa adiacente.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$<replaceable>parametro</replaceable>=</literal></entry>
|
|
|
|
<entry>setta <replaceable>parametro</replaceable> a
|
|
<emphasis>null</emphasis>.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>${<replaceable>parametro</replaceable>-<replaceable>default</replaceable>}</literal></entry>
|
|
|
|
<entry>se <replaceable>parametro</replaceable> non è settato
|
|
allora si usa <replaceable>default</replaceable> come valore.
|
|
<replaceable>parametro</replaceable> non viene resettato.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>${<replaceable>parametro</replaceable>=<replaceable>default</replaceable>}</literal></entry>
|
|
|
|
<entry>se <replaceable>parametro</replaceable> non è settato
|
|
allora lo si setta a <replaceable>default</replaceable> e si usa
|
|
il nuovo valore</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>${<replaceable>parametro</replaceable>+<replaceable>nuovo_valore</replaceable>}</literal></entry>
|
|
|
|
<entry>se <replaceable>parametro</replaceable> è settato
|
|
allora si usa <replaceable>nuovo_valore</replaceable> altrimenti
|
|
non si usa nulla. <replaceable>parametro</replaceable> non viene
|
|
resettato.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>${<replaceable>parametro</replaceable>?<replaceable>messaggio</replaceable>}</literal></entry>
|
|
|
|
<entry>se <replaceable>parametro</replaceable> non è settato
|
|
allora si visualizza il messaggio. Se
|
|
<replaceable>parametro</replaceable> è settato allora si
|
|
usa il valore corrente.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>Non ci sono spazi nei precedenti operatori. Se un due punti (:) viene
|
|
inserito prima di -, =, + o ? allora si effettua prima un test per vedere
|
|
se il parametro ha un settaggio <emphasis>non-nullo</emphasis>.</para>
|
|
|
|
<para>La shell C ha alcuni modi aggiuntivi per la sostituzione di
|
|
parametri:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="1.5in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><literal>$lista[<replaceable>n</replaceable>]</literal></entry>
|
|
|
|
<entry>seleziona l'<replaceable>n-esima</replaceable> parola dalla
|
|
lista</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>${lista[<replaceable>n</replaceable>]}</literal></entry>
|
|
|
|
<entry>come sopra</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$#lista</literal></entry>
|
|
|
|
<entry>riporta il numero di parole in lista</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$?<replaceable>parametro</replaceable></literal></entry>
|
|
|
|
<entry>ritorna 1 se il parametro è settato, 0
|
|
altrimenti</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>${?<replaceable>parametro</replaceable>}</literal></entry>
|
|
|
|
<entry>come sopra</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><literal>$<</literal></entry>
|
|
|
|
<entry>legge una linea da &man.stdin.4;</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>Inoltre la shell C definisce l'array
|
|
<literal>$argv[<replaceable>n</replaceable>]</literal> per
|
|
contenere gli <replaceable>n</replaceable> argomenti della linea di
|
|
comando e <literal>$#argv</literal> per il numero di argomenti, come
|
|
specificato in <link linkend="shell-programming-table-shell-var">Tabella
|
|
9.1</link>.</para>
|
|
|
|
<para>Per illustrare alcune di queste caratteristiche si userà il
|
|
seguente script di prova:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
param0=$0
|
|
test -n "$1" && param1=$1
|
|
test -n "$2" && param2=$2
|
|
test -n "$3" && param3=$3
|
|
echo 0: $param0
|
|
echo "1: ${param1-1}: \c" ;echo $param1
|
|
echo "2: ${param2=2}: \c" ;echo $param2
|
|
echo "3: ${param3+3}: \c" ;echo $param3</programlisting>
|
|
|
|
<para>Inizialmente nello script si verifica con &man.test.1; se la
|
|
variabile esiste; in tal caso si setta il parametro al suo valore.
|
|
Dopo si riportano i valori, effettuando le sostituzioni.</para>
|
|
|
|
<para>Nella prima esecuzione dello script non vengono forniti
|
|
argomenti:</para>
|
|
|
|
<screen>$ <userinput>./parameter.sh</userinput>
|
|
0: ./parameter.sh # trova sempre $0
|
|
1: 1: # sostituisce 1, ma non assegna questo valore
|
|
2: 2: 2 # sostituisce 2 e assegna questo valore
|
|
3: : # non sostituisce</screen>
|
|
|
|
<para>In questa seconda esecuzione dello script si forniscono alcuni
|
|
argomenti:</para>
|
|
|
|
<screen>$ <userinput>./parameter one two three</userinput>
|
|
0: ./parameter.sh # trova sempre $0
|
|
1: one: one # non sostituisce, ha già un valore
|
|
2: two: two # non sostituisce, ha già un valore
|
|
3: 3: three # sostituisce 3 ma non assegna questo valore</screen>
|
|
</sect1>
|
|
|
|
<sect1 id="shell-programming-here-doc">
|
|
<title>Here document</title>
|
|
|
|
<para>Un <emphasis>here document</emphasis> è una forma di quoting
|
|
che permette alle variabili di shell di essere sostituite. È una
|
|
forma speciale di redirezione che inizia con una linea contenente
|
|
solamente <emphasis><<<replaceable>PAROLA</replaceable></emphasis>
|
|
e finisce con una linea contenete solamente
|
|
<emphasis><replaceable>PAROLA</replaceable></emphasis>. Nella shell
|
|
Bourne si può impedire la sostituzione di shell effettuando un
|
|
escape su <emphasis><replaceable>PAROLA</replaceable></emphasis>, mettendo
|
|
un \ davanti a <emphasis><replaceable>PAROLA</replaceable></emphasis>
|
|
sulla linea di redirezione, esempio
|
|
<emphasis><<\<replaceable>PAROLA</replaceable></emphasis>, ma non
|
|
sulla linea finale. Per avere lo stesso effetto con la shell C si mette
|
|
il \ davanti a <emphasis><replaceable>PAROLA</replaceable></emphasis> in
|
|
entrambi i posti.</para>
|
|
|
|
<para>Gli script che seguono illustrano questo meccanismo:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="3.3in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry>per la <emphasis>shell Bourne</emphasis>:</entry>
|
|
|
|
<entry>e per la <emphasis>shell C:</emphasis></entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<programlisting>#!/bin/sh #!/bin/csh -f
|
|
fa=fa set fa = fa
|
|
non="" set non = ""
|
|
cat << EOF cat << EOF
|
|
Questo here document Questo here document
|
|
$non $fa $non $fa
|
|
sostituzione di variabile sostituzione di variabile
|
|
EOF EOF
|
|
cat << \EOF cat << \EOF
|
|
Questo here document Questo here document
|
|
$non $fa $non $fa
|
|
sostituzione di variabile sostituzione di variabile
|
|
EOF \EOF</programlisting>
|
|
|
|
<para>Entrambi gli output producono:</para>
|
|
|
|
<screen>Questo here document
|
|
fa
|
|
sostituzione di variabile
|
|
Questo here document
|
|
$non $fa
|
|
sostituzione di variabile</screen>
|
|
|
|
<para>Nella parte superiore dell'esempio le variabili di shell
|
|
<literal>$non</literal> e <literal>$fa</literal> sono sostituite.
|
|
Nella parte inferiore queste variabili vengono trattate come delle
|
|
semplici stringhe di testo senza effettuare la sostituzione.</para>
|
|
</sect1>
|
|
|
|
<sect1 id="shell-programming-int-input">
|
|
<title>Input interattivo</title>
|
|
|
|
<para>Gli script di shell possono accettare input interattivo per
|
|
inizializzare parametri all'interno dello script stesso.</para>
|
|
|
|
<sect2 id="shell-programming-int-input-sh">
|
|
<title>Sh</title>
|
|
|
|
<para>&man.sh.1; utilizza il comando built-in <command>read</command> per
|
|
leggere una linea di input, esempio:</para>
|
|
|
|
<para><command>read param</command></para>
|
|
|
|
<para>Questo può essere illustrato con un semplice script:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
echo "Inserisci una frase \c" # /bin/echo che richiede "\c" per
|
|
# impedire un newline
|
|
read param
|
|
echo param=$param</programlisting>
|
|
|
|
<para>Quando questo script viene eseguito, viene richiesto l'input, che
|
|
viene poi mostrato nel risultato:</para>
|
|
|
|
<screen>$ <userinput>./read.sh</userinput>
|
|
<prompt>Inserisci una frase</prompt> <userinput>hello frank</userinput> # E' stato digitato hello frank <return>
|
|
param=hello frank</screen>
|
|
</sect2>
|
|
|
|
<sect2 id="shell-programming-int-input-csh">
|
|
<title>Csh</title>
|
|
|
|
<para>&man.csh.1; usa il simbolo <literal>$<</literal> per leggere una
|
|
linea da &man.stdin.4;, esempio:</para>
|
|
|
|
<para><command>set param = $<</command></para>
|
|
|
|
<para>Gli spazi bianchi intorno al segno di uguale sono importanti.
|
|
Il seguente script illustra come usarlo:</para>
|
|
|
|
<programlisting>#!/bin/csh -f
|
|
echo -n "Inserisci una frase" # Questo echo built-in richiede -n
|
|
# per impedire un newline
|
|
set param = $<
|
|
echo param=$param</programlisting>
|
|
|
|
<para>Quindi chiede l'input e lo mostra nel risultato:</para>
|
|
|
|
<screen>&prompt.user; <userinput>./read.csh</userinput>
|
|
<prompt>Inserisci una frase</prompt> <userinput>hello frank</userinput> # E' stato digitato hello frank <return>
|
|
param=hello frank</screen>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="shell-programming-functions">
|
|
<title>Funzioni</title>
|
|
|
|
<para>La shell Bourne permette di definire funzioni. Queste sono molto
|
|
simili agli alias della shell C, ma permettono più
|
|
flessibilità. Una funzione ha la forma:</para>
|
|
|
|
<para><command><replaceable>funzione</replaceable> () {
|
|
<replaceable>comando</replaceable>; }</command></para>
|
|
|
|
<para>dove lo spazio dopo { e il punto e virgola (;) sono obbligatori;
|
|
il punto e virgola può essere omesso facendo precedere a } un
|
|
newline. Spazi e newline aggiuntivi sono permessi.
|
|
Alcuni esempi di funzioni possono essere visti nel semplice file
|
|
<filename>.profile</filename> discusso nei primi capitoli, dove si avevano
|
|
delle funzioni per <command>ls</command> e <command>ll</command>:</para>
|
|
|
|
<para><command>ls() { /bin/ls -sbF "$@";}</command></para>
|
|
|
|
<para><command>ll() { ls -al "$@";}</command></para>
|
|
|
|
<para>La prima funzione ridefinisce &man.ls.1; affinchè le opzioni
|
|
<option>-sbF</option> siano sempre fornite dal comando standard
|
|
<command>/bin/ls</command> e in modo da agire in base all'input fornito,
|
|
<literal>$@</literal>. La seconda di queste funzioni prende il valore
|
|
corrente di <command>ls</command> (la funzione precedente) e aggiunge le
|
|
opzioni <option>-al</option>.</para>
|
|
|
|
<para>Le funzioni sono molto utili negli script di shell. Il seguente
|
|
script è una versione semplificata di uno script utilizzato per
|
|
effettuare automaticamente il backup su nastro delle partizioni di
|
|
sistema.</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
# Script cron per un completo backup del sistema
|
|
HOST=`/bin/uname -n`
|
|
admin=frank
|
|
Mt=/bin/mt
|
|
Dump=/usr/sbin/ufsdump
|
|
Mail=/bin/mailx
|
|
device=/dev/rmt/0n
|
|
Rewind="$Mt -f $device rewind"
|
|
Offline="$Mt -f $device rewoffl"
|
|
# Failure - exit
|
|
failure () {
|
|
$Mail -s "Backup fallito - $HOST" $admin << EOF_failure
|
|
$HOST
|
|
Script cron backup fallito. A quanto pare non c'è il nastro nel dispositivo.
|
|
EOF_failure
|
|
exit 1
|
|
}
|
|
# Dump failure - exit
|
|
dumpfail () {
|
|
$Mail -s "Backup fallito - $HOST" $admin << EOF_dumpfail
|
|
$HOST
|
|
Script cron backup fallito. A quanto pare non c'è il nastro nel dispositivo.
|
|
EOF_dumpfail
|
|
exit 1
|
|
}
|
|
# Success
|
|
success () {
|
|
$Mail -s "Backup completato con successo - $HOST" $admin << EOF_success
|
|
$HOST
|
|
Script cron backup apparentemente riuscito. Il file /etc/dumpdates è:
|
|
`/bin/cat /etc/dumpdates`
|
|
EOF_success
|
|
}
|
|
# Conferma nastro nel device
|
|
$Rewind || failure
|
|
$Dump 0uf $device / || dumpfail
|
|
$Dump 0uf $device /usr || dumpfail
|
|
$Dump 0uf $device /home || dumpfail
|
|
$Dump 0uf $device /var || dumpfail
|
|
($Dump 0uf $device /var/spool/mail || dumpfail) && success
|
|
$Offline</programlisting>
|
|
|
|
<para>Questo script illustra alcuni argomenti che sono stati trattati in
|
|
questo documento. Lo script inizia settando i valori di alcuni parametri.
|
|
<literal>HOST</literal> viene inizializzato dall'output di un comando,
|
|
<literal>admin</literal> è l'amministratore di sistema,
|
|
<literal>Mt</literal>, <literal>Dump</literal> e <literal>Mail</literal>
|
|
sono nomi di programmi, <literal>device</literal> è il dispositivo
|
|
speciale usato per accedere al nastro, <literal>Rewind</literal> e
|
|
<literal>Offline</literal> contengono i comandi rispettivamente per
|
|
riavvolgere e scaricare il nastro usando il riferimento
|
|
<literal>Mt</literal> e le necessarie opzioni. Vengono definite
|
|
tre funzioni: <command>failure</command>, <command>dumpfail</command> e
|
|
<command>success</command>. Tutte le funzioni in questo script utilizzano
|
|
la forma <emphasis>here document</emphasis> per realizzare il contenuto
|
|
della funzione stessa. Si introducono ora gli operatori logici
|
|
<emphasis>OR</emphasis> (<emphasis>||</emphasis>) e
|
|
<emphasis>AND</emphasis> (<emphasis>&&</emphasis>); ciascuno è
|
|
posizionato tra una coppia di comandi. Per l'operatore
|
|
<emphasis>OR</emphasis>, il secondo comando viene eseguito solamente se
|
|
il primo comando non è stato completato con successo. Per
|
|
l'operatore <emphasis>AND</emphasis>, il secondo comando viene
|
|
eseguito solamente se il primo comando è stato completato con
|
|
successo.</para>
|
|
|
|
<para>Lo scopo principale dello script è realizzare i comandi
|
|
<command>Dump</command>, ad esempio copiando i file system specificati.
|
|
Prima si tenta di eseguire il riavvolgimento del nastro. Se questo
|
|
fallisce, <literal>|| failure</literal>, si esegue la funzione
|
|
<command>failure</command> e si esce dal programma. Se invece questo ha
|
|
successo si procede con il backup a turno di ogni partizione, ogni volta
|
|
verificando che questa operazione sia completamente riuscita
|
|
(<literal>|| dumpfail</literal>). Se questa operazione non viene eseguita
|
|
completamente con successo si esegue la procedura
|
|
<command>dumpfail</command> e si esce. Se l'ultimo backup ha successo si
|
|
procede con la funzione <command>success</command> (<literal>(...) &&
|
|
success</literal>). In fine si riavvolge il nastro e lo si manda fuori
|
|
linea affinchè altri utenti non possano accidentalmente scriverci
|
|
sopra.</para>
|
|
</sect1>
|
|
|
|
<sect1 id="shell-programming-control-comm">
|
|
<title>Comandi di controllo</title>
|
|
|
|
<sect2 id="shell-programming-control-comm-if">
|
|
<title>Condizionale if</title>
|
|
|
|
<para>L'espressione condizionale <command>if</command> è
|
|
disponibile in entrambe le shell, ma con una diversa sintassi.</para>
|
|
|
|
<sect3 id="shell-programming-control-comm-if-sh">
|
|
<title>Sh</title>
|
|
|
|
<programlisting><command>if</command> <replaceable>condizione1</replaceable>
|
|
<command>then</command>
|
|
lista di comandi se <replaceable>condizione1</replaceable> è vera (true)
|
|
[<command>elif</command> <replaceable>condizione2</replaceable>
|
|
<command>then</command> lista di comandi se <replaceable>condizione2</replaceable> è vera (true)]
|
|
[<command>else</command>
|
|
lista di comandi se <replaceable>condizione1</replaceable> è falsa (false)]
|
|
<command>fi</command></programlisting>
|
|
|
|
<para>Le condizioni sono sottoposte usualmente al comando &man.test.1; o
|
|
<command>[]</command> (Vedere la <link
|
|
linkend="shell-programming-control-comm-test">sezione 9.9.6</link>).
|
|
L'<command>if</command> e <command>then</command> devono essere
|
|
separati con un newline o un punto e virgola (;).</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
if [ $# -ge 2 ]
|
|
then
|
|
echo $2
|
|
elif [ $# -eq 1 ]; then
|
|
echo $1
|
|
else
|
|
echo Nessun input
|
|
fi</programlisting>
|
|
|
|
<para>Sono richiesti degli spazi nel formato della condizione di
|
|
&man.test.1;, uno dopo <command>[</command> e uno prima di
|
|
<command>]</command>. Questo script potrebbe comportarsi in modo
|
|
differente a seconda che ci siano zero, uno o più argomenti su
|
|
linea di comando. Iniziando con nessun argomento:</para>
|
|
|
|
<screen>$ <userinput>./if.sh</userinput>
|
|
Nessun input</screen>
|
|
|
|
<para>Ora con un argomento:</para>
|
|
|
|
<screen>$ <userinput>./if.sh one</userinput>
|
|
one</screen>
|
|
|
|
<para>E ora con due argomenti:</para>
|
|
|
|
<screen>$ <userinput>./if.sh one two</userinput>
|
|
two</screen>
|
|
</sect3>
|
|
|
|
<sect3 id="shell-programming-control-comm-if-csh">
|
|
<title>Csh</title>
|
|
|
|
<programlisting><command>if</command> (<replaceable>condizione</replaceable>) <command><replaceable>comando</replaceable></command>
|
|
-oppure-
|
|
<command>if</command> (<replaceable>condizione1</replaceable>) <command>then</command>
|
|
lista di comandi se <replaceable>condizione1</replaceable> è vera (true)
|
|
[<command>else</command> <command>if</command> (<replaceable>condizione2</replaceable>) <command>then</command>
|
|
lista di comandi se <replaceable>condizione2</replaceable> è vera (true)]
|
|
[<command>else</command>
|
|
lista di comandi se <replaceable>condizione1</replaceable> è falsa (false)]
|
|
<command>endif</command></programlisting>
|
|
|
|
<para>L'<command>if</command> e <command>then</command> devono stare
|
|
sulla stessa linea.</para>
|
|
|
|
<programlisting>#!/bin/csh -f
|
|
if ( $#argv >= 2 ) then
|
|
echo $2
|
|
else if ( $#argv == 1 ) then
|
|
echo $1
|
|
else
|
|
echo Nessun input
|
|
endif</programlisting>
|
|
|
|
<para>Di nuovo, questo script potrebbe comportarsi in modo differente a
|
|
seconda che ci siano zero, uno o più argomenti su linea di
|
|
comando. Iniziando con nessun argomento:</para>
|
|
|
|
<screen>&prompt.user; <userinput>./if.csh</userinput>
|
|
Nessun input</screen>
|
|
|
|
<para>Ora con un argomento:</para>
|
|
|
|
<screen>&prompt.user; <userinput>./if.csh one</userinput>
|
|
one</screen>
|
|
|
|
<para>E ora con due argomenti:</para>
|
|
|
|
<screen>&prompt.user; <userinput>./if.csh one two</userinput>
|
|
two</screen>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2 id="shell-programming-control-comm-switch-case">
|
|
<title>Condizionale switch e case</title>
|
|
|
|
<para>Per scegliere tra una serie di valori di tipo stringa relativi a un
|
|
parametro si usa <command>case</command> nella shell Bourne e
|
|
<command>switch</command> nella shell C.</para>
|
|
|
|
<sect3 id="shell-programming-control-comm-switch-case-sh">
|
|
<title>Sh</title>
|
|
|
|
<programlisting><command>case</command> <replaceable>parametro</replaceable> <command>in</command>
|
|
<replaceable>schema1</replaceable>[|<replaceable>schema1a</replaceable>]) <replaceable>lista1 di comandi</replaceable>;;
|
|
<replaceable>schema2</replaceable>) <replaceable>lista2 di comandi</replaceable>
|
|
<replaceable>lista2a di comandi</replaceable>;;
|
|
<replaceable>schema3</replaceable>) <replaceable>lista3 di comandi</replaceable>;;
|
|
*) ;;
|
|
<command>esac</command></programlisting>
|
|
|
|
<para>Si possono usare validi nomi di file meta-caratteri all'interno
|
|
dello schema per il confronto. I ;; concludono ogni scelta e
|
|
possono essere sulla stessa linea della scelta o a seguito di un
|
|
newline, dopo l'ultimo comando per la scelta. Schemi alternativi
|
|
per la scelta di un particolare caso sono separati da una barra
|
|
verticale |, come nel primo schema dell'esempio precedente. I simboli
|
|
wild card ,? per indicare un generico carattere e * per far
|
|
corrispondere alcuni caratteri, possono essere usati singolarmente o
|
|
in modo adiacente per completare stringhe.</para>
|
|
|
|
<para>Questo semplice esempio illustra come usare l'espressione
|
|
condizionale <command>case</command>.</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
case $1 in
|
|
aa|ab) echo A
|
|
;;
|
|
b?) echo "B \c"
|
|
echo $1;;
|
|
c*) echo C;;
|
|
*) echo D;;
|
|
esac</programlisting>
|
|
|
|
<para>Quindi quando si esegue lo script con l'argomento posto sulla
|
|
colonna di sinistra, lo script risponde come sulla colonna di
|
|
destra:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="0.5in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry>aa</entry>
|
|
|
|
<entry>A</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>ab</entry>
|
|
|
|
<entry>A</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>ac</entry>
|
|
|
|
<entry>D</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>bb</entry>
|
|
|
|
<entry>B bb</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>bbb</entry>
|
|
|
|
<entry>D</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>c</entry>
|
|
|
|
<entry>C</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>cc</entry>
|
|
|
|
<entry>C</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry>fff</entry>
|
|
|
|
<entry>D</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</sect3>
|
|
|
|
<sect3 id="shell-programming-control-comm-switch-case-csh">
|
|
<title>Csh</title>
|
|
|
|
<programlisting><command>switch</command> (<replaceable>parametro</replaceable>)
|
|
<command>case</command> <replaceable>schema1</replaceable>:
|
|
<replaceable>lista1 di comandi</replaceable>
|
|
[<command>breaksw</command>]
|
|
<command>case</command> <replaceable>schema2</replaceable>:
|
|
<replaceable>lista2 di comandi</replaceable>
|
|
[<command>breaksw</command>]
|
|
<command>default</command>:
|
|
lista di comandi per il comportamento di default
|
|
[<command>breaksw</command>]
|
|
<command>endsw</command></programlisting>
|
|
|
|
<para><command>breaksw</command> è opzionale e può essere
|
|
usato per interrompere lo switch dopo che si è verificata una
|
|
corrispondenza del valore di tipo stringa del parametro confrontato.
|
|
<command>Switch</command> non accetta | nella lista degli schemi, ma
|
|
permette di unire insieme diverse strutture <command>case</command>
|
|
per fornire un simile risultato. Il seguente script di shell C ha lo
|
|
stesso comportamento dell'esempio precedente, riferito al
|
|
<command>case</command> della shell Bourne.</para>
|
|
|
|
<programlisting>#!/bin/csh -f
|
|
switch ($1)
|
|
case aa:
|
|
case ab:
|
|
echo A
|
|
breaksw
|
|
case b?:
|
|
echo -n "B "
|
|
echo $1
|
|
breaksw
|
|
case c*:
|
|
echo C
|
|
breaksw
|
|
default:
|
|
echo D
|
|
endsw</programlisting>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2 id="shell-programming-control-comm-for-foreach">
|
|
<title>for e foreach</title>
|
|
|
|
<para>Per effettuare un ciclo tra una lista di valori di tipo
|
|
stringa si possono usare i comandi <command>for</command> e
|
|
<command>foreach</command>.</para>
|
|
|
|
<sect3 id="shell-programming-control-comm-for-foreach-sh">
|
|
<title>Sh</title>
|
|
|
|
<programlisting><command>for</command> <replaceable>variabile</replaceable> [<command>in</command> <replaceable>lista_di_valori</replaceable>]
|
|
<command>do</command>
|
|
<replaceable>lista di comandi</replaceable>
|
|
<command>done</command></programlisting>
|
|
|
|
<para>La <replaceable>lista_di_valori</replaceable> è opzionale,
|
|
presupponendo <literal>$@</literal> se nulla viene specificato. Ogni
|
|
valore in questa lista viene sostituito sequenzialmente in
|
|
<replaceable>variabile</replaceable> fino a quando la lista risulta
|
|
vuota. Possono essere usati wild card, che vengono applicati ai
|
|
nomi dei file nella directory corrente. Di seguito si illustra il
|
|
ciclo <command>for</command> che copia tutti i file che finiscono con
|
|
<filename>.old</filename> negli stessi nomi che finiscono però
|
|
con <filename>.new</filename>. In questi esempi l'utility
|
|
&man.basename.1; estrae la parte base del nome affinchè
|
|
si possa modificarne l'estensione.</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
for file in *.old
|
|
do
|
|
newf=`basename $file .old`
|
|
cp $file $newf.new
|
|
done</programlisting>
|
|
</sect3>
|
|
|
|
<sect3 id="shell-programming-control-comm-for-foreach-csh">
|
|
<title>Csh</title>
|
|
|
|
<programlisting><command>foreach</command> <replaceable>variabile</replaceable> (<replaceable>lista_di_valori</replaceable>)
|
|
<replaceable>lista di comandi</replaceable>
|
|
<command>end</command></programlisting>
|
|
|
|
<para>L'equivalente script in shell C per copiare tutti i file con
|
|
estensione <filename>.old</filename> negli stessi file con estensione
|
|
<filename>.new</filename> è:</para>
|
|
|
|
<programlisting>#!/bin/csh -f
|
|
foreach file (*.old)
|
|
set newf = `basename $file .old`
|
|
cp $file $newf.new
|
|
end</programlisting>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2 id="shell-programming-control-comm-while">
|
|
<title>while</title>
|
|
|
|
<para>Il comando <command>while</command> permette di effettuare il ciclo
|
|
sempre che la condizione sia vera.</para>
|
|
|
|
<sect3 id="shell-programming-control-comm-while-sh">
|
|
<title>Sh</title>
|
|
|
|
<programlisting><command>while</command> <replaceable>condizione</replaceable>
|
|
<command>do</command>
|
|
<replaceable>lista di comandi</replaceable>
|
|
[<command>break</command>]
|
|
[<command>continue</command>]
|
|
<command>done</command></programlisting>
|
|
|
|
<para>Un semplice script per illustrare il ciclo
|
|
<command>while</command> è:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
while [ $# -gt 0 ]
|
|
do
|
|
echo $1
|
|
shift
|
|
done</programlisting>
|
|
|
|
<para>Questo script prende la lista degli argomenti, ne visualizza il
|
|
primo, quindi effettua uno shift nella lista verso sinistra, perdendo
|
|
il primo elemento originale. Il ciclo viene ripetuto fino a quando
|
|
tutti gli argomenti sono stati spostati fuori dalla lista.</para>
|
|
|
|
<screen>$ <userinput>./while.sh one two three</userinput>
|
|
one
|
|
two
|
|
three</screen>
|
|
</sect3>
|
|
|
|
<sect3 id="shell-programming-control-comm-while-csh">
|
|
<title>Csh</title>
|
|
|
|
<programlisting><command>while</command> (<replaceable>condizione</replaceable>)
|
|
<replaceable>lista di comandi</replaceable>
|
|
[<command>break</command>]
|
|
[<command>continue</command>]
|
|
<command>end</command></programlisting>
|
|
|
|
<para>Se si vuole che la condizione sia sempre vera si specifica 1
|
|
all'interno del test condizionale.</para>
|
|
|
|
<para>Lo script di shell C equivalente a quello precedente
|
|
è:</para>
|
|
|
|
<programlisting>#!/bin/csh -f
|
|
while ($#argv != 0 )
|
|
echo $argv[1]
|
|
shift
|
|
end</programlisting>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2 id="shell-programming-control-comm-until">
|
|
<title>until</title>
|
|
|
|
<para>Questo costrutto di ciclo è solamente disponibile per la
|
|
shell Bourne.</para>
|
|
|
|
<programlisting><command>until</command> <replaceable>condizione</replaceable>
|
|
<command>do</command>
|
|
lista di comandi se la condizione è falsa
|
|
<command>done</command></programlisting>
|
|
|
|
<para>La condizione viene verificata all'inizio di ogni ciclo e il ciclo
|
|
termina quando la condizione è vera.</para>
|
|
|
|
<para>Uno script equivalente all'esempio del <command>while</command>
|
|
precedente è:</para>
|
|
|
|
<programlisting>#!/bin/sh
|
|
until [ $# -le 0 ]
|
|
do
|
|
echo $1
|
|
shift
|
|
done</programlisting>
|
|
|
|
<para>Si noti che qui si verifica per <emphasis>minore o
|
|
uguale</emphasis>, piuttosto che per <emphasis>maggiore</emphasis>,
|
|
poichè il ciclo <command>until</command> viene abilitato da una
|
|
condizione <emphasis>falsa</emphasis>.</para>
|
|
|
|
<para>Sia il ciclo <command>until</command> che il
|
|
<command>while</command> sono solamente eseguiti se la condizione
|
|
è soddisfatta. La condizione viene valutata prima
|
|
dell'esecuzione dei comandi.</para>
|
|
</sect2>
|
|
|
|
<sect2 id="shell-programming-control-comm-test">
|
|
<title>test</title>
|
|
|
|
<para>Le espressioni condizionali vengono valutate per valori
|
|
<emphasis>veri</emphasis> o <emphasis>falsi</emphasis>. Questo, di
|
|
solito, viene realizzato con &man.test.1; o equivalentemente con i suoi
|
|
operatori <command>[]</command>. Se la condizione viene valutata vera,
|
|
viene settato uno stato di uscita zero (<emphasis>TRUE</emphasis>),
|
|
altrimenti viene settato uno stato di uscita non-zero
|
|
(<emphasis>FALSE</emphasis>). Se non ci sono argomenti viene settato
|
|
uno stato di uscita non-zero. Gli operatori utilizzati nelle
|
|
espressioni condizionali della shell Bourne sono mostrati qui
|
|
sotto.</para>
|
|
|
|
<para>Per i <emphasis>nomi di file</emphasis> le opzioni per
|
|
&man.test.1; sono date con la sintassi seguente:</para>
|
|
|
|
<para><option>-<replaceable>opzione</replaceable></option>
|
|
<replaceable>filename</replaceable></para>
|
|
|
|
<para>Le opzioni di &man.test.1; disponibili per i
|
|
<emphasis>file</emphasis> includono:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="1in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><option>-r</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è leggibile</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-w</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è scrivibile</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-x</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è eseguibile</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-f</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è un file regolare (o per
|
|
&man.csh.1; esiste e non è una directory)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-d</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è una directory</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-h</option> o <option>-L</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è un link
|
|
simbolico</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-c</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è un file speciale a
|
|
caratteri (ad esempio un dispositivo al quale si accede un
|
|
carattere alla volta)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-b</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è un file speciale a
|
|
blocchi (ad esempio un dispositivo al quale si accede in blocchi
|
|
di dati)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-p</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è un file pipe
|
|
(fifo)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-u</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è setuid (ad esempio ha il
|
|
bit set-user-id settato a s o S nel terzo bit)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-g</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è setgid (ad esempio ha il
|
|
bit set-group-id settato a s o S nel sesto bit)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-k</option></entry>
|
|
|
|
<entry>vero se il file esiste e ha lo sticky bit settato (una t
|
|
nel nono bit)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-s</option></entry>
|
|
|
|
<entry>vero se il file esiste ed ha una dimensione maggiore di
|
|
zero</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>C'è un test per i <emphasis>descrittori di
|
|
file</emphasis>:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="2in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><option>-t
|
|
[<replaceable>descrittore_file</replaceable>]</option></entry>
|
|
|
|
<entry>vero se l'aperto descrittore del file specificato (1,
|
|
&man.stdout.4;, di default) è associato ad un
|
|
terminale</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>Ci sono test per le <emphasis>stringhe</emphasis>:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="2in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><option>-z
|
|
<replaceable>stringa</replaceable></option></entry>
|
|
|
|
<entry>vero se la lunghezza della stringa è zero</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-n
|
|
<replaceable>stringa</replaceable></option></entry>
|
|
|
|
<entry>vero se la lunghezza della stringa non è
|
|
zero</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option><replaceable>stringa1</replaceable> =
|
|
<replaceable>stringa2</replaceable></option></entry>
|
|
|
|
<entry>vero se <replaceable>stringa1</replaceable> è
|
|
identica a <replaceable>stringa2</replaceable></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option><replaceable>stringa1</replaceable> !=
|
|
<replaceable>stringa2</replaceable></option></entry>
|
|
|
|
<entry>vero se <replaceable>stringa1</replaceable> non è
|
|
identica a <replaceable>stringa2</replaceable></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><replaceable>stringa</replaceable></entry>
|
|
|
|
<entry>vero se la stringa non è nulla</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>Ci sono dei confronti per gli interi:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="1.5in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><option><replaceable>n1</replaceable> -eq
|
|
<replaceable>n2</replaceable></option></entry>
|
|
|
|
<entry>vero se gli interi <replaceable>n1</replaceable> e
|
|
<replaceable>n2</replaceable> sono uguali</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option><replaceable>n1</replaceable> -ne
|
|
<replaceable>n2</replaceable></option></entry>
|
|
|
|
<entry>vero se gli interi <replaceable>n1</replaceable> e
|
|
<replaceable>n2</replaceable> non sono uguali</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option><replaceable>n1</replaceable> -gt
|
|
<replaceable>n2</replaceable></option></entry>
|
|
|
|
<entry>vero se l'intero <replaceable>n1</replaceable> è
|
|
maggiore dell'intero <replaceable>n2</replaceable></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option><replaceable>n1</replaceable> -ge
|
|
<replaceable>n2</replaceable></option></entry>
|
|
|
|
<entry>vero se l'intero <replaceable>n1</replaceable> è
|
|
maggiore o uguale dell'intero
|
|
<replaceable>n2</replaceable></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option><replaceable>n1</replaceable> -lt
|
|
<replaceable>n2</replaceable></option></entry>
|
|
|
|
<entry>vero se l'intero <replaceable>n1</replaceable> è
|
|
minore dell'intero <replaceable>n2</replaceable></entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option><replaceable>n1</replaceable> -le
|
|
<replaceable>n2</replaceable></option></entry>
|
|
|
|
<entry>vero se l'intero <replaceable>n1</replaceable> è
|
|
minore o uguale dell'intero
|
|
<replaceable>n2</replaceable></entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>Sono disponibili i seguenti <emphasis>operatori
|
|
logici</emphasis>:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="0.5in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><option>!</option></entry>
|
|
|
|
<entry>negazione (unaria)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-a</option></entry>
|
|
|
|
<entry>and (binario)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-o</option></entry>
|
|
|
|
<entry>or (binario)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>()</option></entry>
|
|
|
|
<entry>le espressioni all'interno di ( ) vengono raggruppate
|
|
insieme. Può essere necessario quotare le parentesi ( )
|
|
per impedire alla shell di interpretarle.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</sect2>
|
|
|
|
<sect2 id="shell-programming-control-comm-csh-log-rel-op">
|
|
<title>Operatori relazionali e logici della shell C</title>
|
|
|
|
<para>La shell C possiede un suo set di operatori logici e relazionali
|
|
built-in. In ordine decrescente di priorità questi sono:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="1.5in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><command>(...)</command></entry>
|
|
|
|
<entry>raggruppa espressioni con ( )</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>~</command></entry>
|
|
|
|
<entry>inverso (il suo complemento)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>!</command></entry>
|
|
|
|
<entry>negazione logica</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>*, /, %</command></entry>
|
|
|
|
<entry>moltiplicazione, divisione, modulo</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>+, -</command></entry>
|
|
|
|
<entry>addizione, sottrazione</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command><<, >></command></entry>
|
|
|
|
<entry>shift a sinistra di bit, shift a destra di bit</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command><=</command></entry>
|
|
|
|
<entry>minore o uguale</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>>=</command></entry>
|
|
|
|
<entry>maggiore o uguale</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command><</command></entry>
|
|
|
|
<entry>minore</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>></command></entry>
|
|
|
|
<entry>maggiore</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>= =</command></entry>
|
|
|
|
<entry>uguale</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>!=</command></entry>
|
|
|
|
<entry>non uguale</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>=~</command></entry>
|
|
|
|
<entry>uguale a stringa</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>!~</command></entry>
|
|
|
|
<entry>non uguale a stringa</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>&</command></entry>
|
|
|
|
<entry>AND bit</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>^</command></entry>
|
|
|
|
<entry>XOR bit (or esclusivo)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>|</command></entry>
|
|
|
|
<entry>OR bit</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>&&</command></entry>
|
|
|
|
<entry>AND logico</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>||</command></entry>
|
|
|
|
<entry>OR logico</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><command>{<replaceable>comando</replaceable>}</command></entry>
|
|
|
|
<entry>vero (1) se il comando termina con uno stato di uscita 0,
|
|
falso (0) altrimenti.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>Inoltre la shell C permette richieste sul tipo e sui permessi dei
|
|
file con gli operatori seguenti:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<colspec colwidth="1in">
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><option>-r</option></entry>
|
|
|
|
<entry>ritorna vero (1) se il file esiste ed è leggibile,
|
|
altrimenti ritorna falso (0)</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-w</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è scrivibile</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-x</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è eseguibile</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-f</option></entry>
|
|
|
|
<entry>vero se il file esiste e non è una directory</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-d</option></entry>
|
|
|
|
<entry>vero se il file esiste ed è una directory</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-e</option></entry>
|
|
|
|
<entry>vero se il file esiste</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-o</option></entry>
|
|
|
|
<entry>vero se l'utente corrente è il proprietario del
|
|
file</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><option>-z</option></entry>
|
|
|
|
<entry>vero se il file ha una lunghezza zero (file vuoto)</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</sect2>
|
|
</sect1>
|
|
</chapter>
|
|
|
|
<!--
|
|
Local Variables:
|
|
mode: sgml
|
|
sgml-indent-data: t
|
|
sgml-omittag: nil
|
|
sgml-always-quote-attributes: t
|
|
sgml-parent-document: ("../book.sgml" "book" "chapter")
|
|
End:
|
|
--> |