Titolo        Prerequisiti

C shell script
Meccanismi di sostituzione
History substitution
Variabili
Alias substitution
File name substitution
Quoting di comandi
Istruzioni cshell
Esempi di script csh (1)
Directory e file
Alcuni comandi UNIX
Ridirezione e pipelining
Altri comandi UNIX
Esecuzione foreground e background
Exit status dei comandi.
... ancora comandi UNIX
Espressioni regolari
Variabili di environment.
Variabili csh predefinite
Esempi di script csh (2)
Elenco comandi UNIX
Funzioni csh built-in

Valeria Gusulfino
valeria@fauser.edu

 

Il comando csh è un interprete di comandi

ha funzionalità di job control

ha una sintassi simile al linguaggio C

ha un insieme di funzioni built-in che implementa direttamente

legge, traduce e manda in esecuzione comandi

interpreta C shell script, che sono file contenenti istruzioni eseguibili

può essere attivato al prompt, in uno script o in una sessione di login

Ogni volta che viene eseguito il comando csh esso esegue i comandi contenuti nel file .cshrc contenuto nella home directory dell’utente configurando il proprio ambiente.

L’interprete dei comandi csh viene attivato al termine della validazione di un utente (login: password:) se, per quell’utente, nel file /etc/passwd lo shell è configurato come /bin/csh. In questo caso l’ambiente della sessione di login è configurato anche dai comandi contenuti nel file .login. Quando la sessione di login termina (logout:) vengono eseguiti i comandi contenuti nel file .logout.

C shell script

E' un file contenente comandi e/o istruzioni cshell.

il primo carattere deve essere ‘#’

63> cat elenco
# elenca il contenuto dei file rubrica*
cd ~valeria
page rubrica*
64> ls -l elenco
-rw-r--r-- 1 ..... .... elenco
65>

per eseguire uno script C Shell si può:

invocare esplicitamente csh passando come argomento il nome del file che contiene lo script; in questo caso viene attivato un nuovo processo cshell, diverso dallo cshell attivo al prompt, che si fa carico di eseguire ciò che è specificato nello script

65> csh elenco
... ...
67>

rendere eseguibile il file che contiene lo script, utilizzando il comando chmod, che permette di cambiare le proprietà di lettura, scrittura ed esecuzione del file, e successivamente mandare in esecuzione lo script. In questo caso si ottiene la creazione di un nuovo comando dedicato allo svolgimento di una nuova azione complessa non prevista dal sistema

65> chmod +x elenco
66> elenco
... ...
67>

Meccanismi di sostituzione

Csh effettua diverse trasformazioni sugli input che riceve e sono, nell’ordine:

history

alias

variabili

file name

 

History substitution

Permette di utilizzare parole da comandi precedentemente digitati come parti di nuovi comandi. Questo permette di riutilizzare comandi, argomenti o correggere errori.

Un certo numero di comandi viene salvato nella lista di history (la cui lunghezza dipende dal valore delle variabili history e savehist).

Il comando history visualizza l’elenco degli ultimi comandi digitati, ogni comando è preceduto da un numero che lo identifica univocamente (event number).

Il carattere ! segnala l’inizio di una history substitution.

Ad esempio per far rieseguire il comando 52 della lista di history

64>!52
cd /etc
65>

oppure per far rieseguire l’ultima compilazione

66>!cc
cc prova.c
67>

o per modificare una parte dell’ultimo comando

67>^prova^ordina
68>cc ordina.c
69>

Alias substitution

Csh mantiene una lista di sinonimi che può essere definita, modificata e visualizzata con i comandi alias e unalias.

alias senza argomenti visualizza la lista dei sinonimi alias

alias con argomenti definisce un nuovo sinonimo alias ls ‘ls –l’

unalias elimina la definizione di un sinonimo unalias ls

Quando csh esamina un comando scandisce ogni parola per verificare se corrisponde ad un alias, in caso affermativo ne effettua la sostituzione con la sua definizione.

Variabili

è possibile creare delle variabili shell simili a quelle dei linguaggi di programmazione ad alto livello

rendono flessibili e più potenti i comandi

possono essere utilizzate in script C shell o in comandi interattivi

il nome di una variabile

deve iniziare con una lettera

può contenere lettere,numeri ed il carattere ‘_’

deve avere lunghezza massima di 80 caratteri

ogni variabile ha come valore una lista di zero o più stringhe

il comando @ permette di considerare la stringa come un numero e quindi di effettuare operazioni aritmetiche sulle variabili

possono essere inizializzate mediante

assegnamento set unset

ridirezione da stdin

un riferimento ad una variabile priva di valore provoca una segnalazione di errore

una variabile csh è un’array che contiene 0 o più stringhe

$nome corrisponde a tutta la lista di stringhe
$nome[1] corrisponde alla prima stringa
$nome[n] corrisponde all’n-esima stringa
$#nome corrisponde al numero di stringhe
$?nome restituisce vero se la variabile è definita

Per assegnare un valore ad una variabile

set varname=value

il comando set senza argomenti visualizza l’elenco delle variabili csh ed il valore associato

67> set a=3
68> set
a 3
argv ()
cwd /usr/users/valeria
... ....
69>

Per riferire al contenuto di una variabile si premette il carattere ‘$’ al nome della variabile

69>echo "Directory corrente: $cwd"
Directory corrente: /usr/users/valeria
70>

il comando echo visualizza il messaggio specificato sostituendo alla variabile il suo valore

Per cancellare la definizione di una variabile

70> unset a
71>

Possono essere associati valori multipli ad una variabile

71> set direc=(/ /bin /etc /lib)
72> echo $direc
/ /bin /etc /lib
73> echo $direc[2]
/bin
74> echo $direc[2-4]
/bin /etc /lib
75> echo $direc[3-]
/etc /lib
76> echo $#direc
4
77> set i=1
78> echo $direc[$i]
/
79>

E’ possibile inizializzare una variabile da stdin

79> cat elenco
#csh
echo -n ‘Sei sicuro ? ‘
set ans=$<
if ( $ans == "no" ) then
exit 1
else
page rubrica*
endif
80> elenco
Sei sicuro ? si
... ...
81>

echo -n non va a capo alla terminazione della scrittura.

è possibile assegnare valori ad una variabile durante la sua valutazione

echo ${ans="no"}

è possibile far assumere ad una variabile il valore dell’output di un comando

81> set userlist=`who`
82> echo $userlist
valeria tty01
corso1 tty02
83>

83> set userlist=`who | awk ‘{print $1}’`
84> echo $userlist
valeria
corso1
85>

 

le parole che costituiscono un comando sono viste da C shell come parametri

quando un comando viene eseguito vengono stabiliti i valori attuali dei parametri

i valori attuali dei parametri al momento della chiamata vengono memorizzati in una variabile argv

è possibile riferire ad un particolare parametro specificandone la posizione

l’utilizzo dei parametri negli script csh permette di ottenere una maggiore flessibilità

 

Negli script si specificano i parametri formali che, al momento dell’esecuzione, assumono i valori dei parametri attuali specificati nella linea di comando.

87>cat arglist
#csh visualizza la lista degli argomenti
echo $argv
echo $argv[1]
echo $argv[3]
echo $argv[2-3]
echo $0
88> arglist p1 p2 p3
p1 p2 p3
p1
p3
p2 p3
arglist
89>

L’associazione fra parametri formali ed attuali è posizionale.

89> cat backup
#csh
cd ~/$argv[1]
cp $argv[2] tmp.dat
90> backup doc document argv[1]=doc argv[2]=document
91> backup c prog.c argv[1]=c argv[2]=prog.c
92>

L’esecuzione dello script backup fallisce se l’utente non specifica i due argomenti per ovviare a questo problema è possibile controllare il numero di parametri del comando.

92> cat backup
#csh
if ($#argv < 2) then
echo $0": usage: backup dir file"
exit 1
endif
cd ~/$argv[1]
cp $argv[2] tmp.dat
93>

Quoting di comandi

In un comando possono essere presenti diversi tipi di apici:

     il contenuto non viene esaminato dallo shell; permette l’utilizzo di metacaratteri negli argomenti di comandi (alias ll ‘ls -l \!*’)

"     permette la sostituzione di variabili cshell, con il corrispondente valore, all’interno della stringa fra " "; in questo caso viene fatta prima l’espansione e quindi il comando viene eseguito (set prompt = "$HOSTNAME.\!> ")

`     permette di usare l’output di un comando o pipeline di comandi come argomenti di altri comandi; il comando fra ` ` viene eseguito, il suo output viene catturato dallo shell e passato al comando specificato (cat `ls *.c`>> c)

Istruzioni cshell

I commenti iniziano con il carattere ‘#’ e possono comparire in qualsiasi posizione la prima linea di uno script deve essere un commento.

istruzione if

if (<expr>) then
<commands>
else
<commands>
endif

oppure

if (<expr>) <command>

istruzione for

foreach <var> (<varlist>)
<commands>
end

istruzione while

while (<expr>)
<commands>
end

istruzione elseif

if (<expr>) then
<commands>
else if (<expr1>) then
<commands>
else
<commands>
endif

istruzione switch (selettore multiplo)

switch (<word>)

case val1:

<commands>
breaksw

............... ..................
case valn:

<commands>
breaksw

default:

<commands>

endsw

istruzione shift

senza parametri sposta a sinistra i parametri posizionali

avendo come parametro una variabile di tipo array di strighe sposta a sinistra gli elementi dell’array

tipi di operatori nelle espressioni

relazionali

== uguale != diverso
> maggiore < minore
>= maggiore o uguale
<= minore o uguale

logici

&& and logico
| | or logico

test sui file

-r permesso di lettura per l’utente
-w permesso di scrittura per l’utente
-x permesso di esecuzione per l’utente
-e il file esiste
-o l’utente è il proprietario
-z il file è vuoto
-f è un file (non una directory)
-d è una directory

Esempi di script csh  (1)

#
# manda in stampa i file specificati sulla linea di comando

foreach i ($argv)
echo ‘Stampa il file $i ...’

lpr $i

end

#
# cancella un file in modo interattivo se non è una directory e se la risposta è Y o y

echo -n "Cancello $1 ? "
set ans=`head -1`
if ((($ans=="Y") | | ($ans=="y")) && (-f $1)) then

rm $1

endif

Directory e file

Home directory

directory sulla quale si è posizionati dopo il login

è associata staticamente all'account

Working directory

directory sulla quale si è posizionati in un determinato istante

il comando cd permette di cambiare la propria working directory navigando nell'albero del file system

Il comando pwd (print working directory) visualizza il nome associato alla directory corrente

Ogni directory contiene almeno due file

.      riferisce alla directory stessa

..     riferisce alla directory padre

Per spostarsi nel file system si usa il comando cd directory-name

il comando cd senza argomento riporta sulla home directory

61> cd /usr/users
62> pwd
/usr/users
63> cd valeria
64> pwd
/usr/users/valeria
65> cd
66> pwd
/studenti/corso/corso1
67> cd ~corso2
68> pwd
/studenti/corso/corso2
69>

Nomi di file

Per ogni file esiste:

Full pathname: si ottiene concatenando alla root directory / i nomi di tutte le directory, separate dal carattere /, che si incontrano percorrendo l'albero del file system a partire dalla root, fino al file riferito

Relative pathname: si ottiene concatenando tra di loro i nomi di tutte le directory, separati dal carattere /, che si incontrano a partire dalla working directory, fino al file riferito

File name substitution

I metacaratteri sono caratteri che vengono interpretati dallo shell, permettono di rendere più generici (o più potenti) i comandi

* viene interpretato come una qualsiasi stringa, compresa la stringa nulla

? viene interpretato come un qualsiasi carattere

[charlist] viene interpretato come un carattere tra quelli elencati tra [ ]

{str1, str2, ..., strN} viene interpretato come una qualsiasi stringa fra quelle elencate tra { }

~ viene interpretato come la home directory dell’utente

~user viene interpretato come la home directory dell’utente user

172>ls -a
. .. .cshrc .login dati.dat dati.txt doc.txt p
p1 p2.c p3 pr1.c pr1.o pr2.c pr2.o prog.c s1.p s2.p
173> ls p?
p1 p3
174> ls p*
p p1 p2 p3 pr1.c pr1.o pr2.c pr2.o prog.c
175> ls ?
p
176>
176> ls ???.p
file not found
177> ls [p-s]2.*
p2.c s2.p
178> ls *[12]*
p1 p2.c pr1.c pr1.o pr2.c
pr2.o s1.p s2.p
179> ls {dati,doc}.*
dati.dat dati.txt doc.txt
180> cd ~
181>pwd
/usr/users/valeria
182> cd ~corso1
183> pwd
/studenti/corso/corso1
184>

Alcuni comandi UNIX

Il comando man, seguito dal nome di un altro comando, visualizza il manuale on line del comando specificato.

185>man ls
.........
186>

Il comando ls visualizza il contenuto di una directory, se non viene specificata alcuna directory, il riferimento è alla working directory.

il comando senza opzioni visualizza un elenco ordinato alfabeticamente dei file contenuti nella directory specificata

l'opzione -l fornisce un long listing dei file

77> pwd
/usr/users/valeria
78> ls -l
total 4 file
drwxrwxr-x     2     valeria    512      May 1992      doc
-rw-rw-r--        1    valeria     1625    Ago 27 12:05 prova
79>

I campi visualizzati hanno il seguente significato:

il primo carattere del primo campo specifica il tipo di file e può valere:

d     directory
-     file ordinario
c     file speciale a caratteri
b     file speciale a blocchi
l     symbolic link

gli altri caratteri del primo campo indicano la maschera dei permessi di accesso al file.

r     permesso di lettura
w     permesso di scrittura o modifica
x     permesso di esecuzione

il secondo campo indica il numero di link

il terzo è il nome del proprietario

il quarto è la dimensione del file in byte

il quinto rappresenta data e ora dell’ultima modifica

il sesto è il nome del file

l'opzione -a visualizza anche i file che iniziano col carattere ‘.’

l’opzione -g, insieme a -l, visualizza il nome del gruppo a cui l’utente appartiene

l'opzione -R elenca ricorsivamente il contenuto delle directory a partire da quella specificata

mkdir per creare una directory

81> cd /studenti/corso/corso1
82> mkdir doc
83> mkdir doc/note
84> mkdir doc/esempi
85>

mv per spostare un file da una directory ad un'altra

85> cd /usr/users/valeria/doc
86> mv documento /usr/users/valeria oppure
86> mv documento ..
87>

e/o per cambiargli il nome

87> mv documento doc.old
87> mv documento ../doc.old
88>

cp per creare una copia di un file

il primo argomento è il file sorgente

il secondo argomento è il file destinatario

88> cd /usr/users/valeria/doc
89> cp doc.old documento
90>

uso di pathname assoluti e relativi

90> cd /usr/users/valeria/doc
91> cp /usr/users/manuela/prova .
92> cp ../testo/rel.txt .
93>

rm per cancellare uno o più file

93> rm /usr/users/valeria/doc/doc.old
93> pwd
/usr/users/valeria
94> rm doc/doc.old
95>

per cancellare una directory vuota

95> rmdir doc
96>

se non è vuota

96> rm doc/*
97> rmdir doc
98>

oppure

96> rm -r doc
97>

l'opzione -r cancella ricorsivamente tutti i file appartenenti all'albero che ha come radice la directory specificata

96> rm -r doc
97>

Per sapere quali sono gli utenti collegati al sistema

51>who
corso1 tty05 jan 30 10:15
corso2 tty01 jan 30 12:30
valeria console jan 30 12:45
52>

Per esaminare il contenuto di un file

57> cat elenco
Rossi Mario A050
Bianchi Elisa B075
Verdi Piero B061
Rossi Giuseppe A003
58>

Per conoscere informazioni su chi è collegato al terminale

52>who am i
valeria console jan 30 12:45
53> whoami
valeria
54>

Per conoscere giorno ed ora

53>date
Fri Jan 30 14:30:01 1998
54>

Esistono diversi formati per visualizzare la data e l’ora o singole unità di tempo.

Ad esempio:

date +%y visualizza l’anno 98
date +%m visualizza il mese come numero 05
date +%h visualizza il mese come stringa May
date +%M visualizza l’ora 09
date +%H visualizza i minuti 15
date +%S visualizza i secondi 21

Possono essere combinati insieme.

Solo root può settare l’ora.

Il comando wc visualizza il numero di linee, parole e caratteri del file specificato l’opzione -c visualizza solo il numero di caratteri del file specificato

l’opzione -w visualizza solo il numero di parole del file specificato

l’opzione -l visualizza solo il numero di linee del file specificato

147> wc elenco
344 elenco
148>

147> wc -l elenco
4 elenco
148>

Il comando head legge e visualizza le prime n linee del file specificato, se il nome del file è omesso legge da stdin

147> head -1 elenco
Bianchi Mario
148>

 

Il comando tail legge e visualizza le ultime n linee del file specificato, se il nome del file è omesso legge da stdin

147> tail -1 elenco
Zanna Bianca
148>

Ridirezione e pipelining

Al momento del login sono automaticamente definiti tre canali di comunicazione fra lo shell e l’utente

Standard Input (stdin) è il canale attraverso il quale l’utente comunica i comandi al sistema; al login viene associato alla tastiera

Standard Output (stdout) è il canale attraverso il quale il sistema comunica all’utente l’output dei comandi; al login viene associato al video

Standard Error (stderr) è il canale attraverso il quale il sistema comunica all’utente i messaggi diagnostici di errore; al login viene associato anch’esso al video

Nella richiesta di esecuzione di un comando è possibile indicare allo shell che i canali di I/O non sono più quelli di default effettuando una ridirezione.

Ridirezione di stdin

< nome

Apre il file nome come standard input.
Per molti comandi, specificare un nome di file senza simboli di ridirezione assume il significato di ridirezione di stdin.

cat elenco  equivale a  cat < elenco

Ridirezione di stdout e stderr

> nome
>! nome
>& nome
>&! nome

Il file nome è usato come standard output; se non esiste viene creato, se esiste il suo contenuto è perso. Se è settata la variabile noclobber il file non deve esistere, altrimenti viene segnalato un errore (per evitare perdite accidentali del contenuto di un file), in questo caso si può usare il ! per evitare il controllo. Il carattere & ridireziona nel file nome anche lo standard error.

>> nome
>> !nome
>>& nome
>>&! nome

Il file nome è usato come standard output come > ma scrive in append. Se è settata la variabile noclobber il file deve esistere, altrimenti viene segnalato un errore, in questo caso si può usare il ! per evitare il controllo.

Per creare un file con input da tastiera

55> cat > elenco
Rossi Mario A050
Bianchi Elisa B075
Verdi Piero B061
Rossi Giuseppe A003
^d
56>

Per aggiungere alla fine di un file con input da tastiera

58> cat >> elenco
Lupo Alberto B04
Carli Guido A027
^d
59>cat elenco
Rossi Mario A050
Bianchi Elisa B075
Verdi Piero B061
Rossi Giuseppe A003
Lupo Alberto B043
Carli Guido A027
60>

145> cat elenco_1 elenco_2 > elenco_tot
146> cat elenco_1 elenco_2 >! elenco_tot
147> cat elenco3 >> elenco_tot
148>

Nel comando cat

l’opzione -n numera tutte le linee

l’opzione -b numera le linee senza contare quelle bianche

Per ridirezionare stdout e stderr nello stesso comando

148> chmod 000 /etc/fstab
chmod: can’t change /etc/fstab: not owner
149> chmod 000 /etc/fstab >& errori
150> cat errori
chmod: can’t change /etc/fstab: not owner
151> (grep "xxx" file1 > message ) >& errori
152> cat file1 >& /dev/null
153>

/dev/null identifica uno special file:

un operazione di lettura equivale a leggere da un file
un operazione di scrittura equivale a scartare il risultato dell’operazione

Filtri

Un filtro è un comando che legge da stdin e scrive su stdout, molti comandi UNIX sono filtri.
E’ possibile fare in modo che lo standard output di un comando diventi lo standard input di un altro comando.
Il comando wc è un filtro, conta il numero di linee che trova sul file specificato (se il file è omesso riferisce a stdin) e lo visualizza su stdout.

147> wc -l
Bart Simpson
Liza Simpsn
^d                       termina   l'acquisizione da stdin
2                         visualizza l'output su stdout
148>

Pipeline

Il principio di utilizzare semplici comandi e concatenarli fra di loro al fine di ottenere un’operazione più complessa è una peculiarità caratterizzante di UNIX.

UNIX mette a disposizione un notevole numero di comandi piuttosto semplici e generici, ciascun utente potrà combinarli fra di loro a seconda delle proprie esigenze, seguendo semplici regole di sintassi, ed arrivare a definirsi un proprio specifico ambiente di lavoro. Solitamente si procede alla definizione di pipelines lavorando in modo incrementale.

Ad ogni passo si esamina il formato dell’output dell’ultimo comando perchè esso dovrà essere correttamente interpretato dal successivo comando che lo utilizzerà come input.

Una pipeline viene creata inserendo il carattere | tra due filtri.

who | wc -l può essere inteso come un nuovo comando che visualizza il numero di utenti collegati al sistema

157> alias user_cnt ‘who | wc -l’
158> user_cnt
5
159>
159> who | sort > list
169>

Altri comandi UNIX

sort è un filtro, ordina alfabeticamente linee di testo, la forma generale è:

sort [opzioni] [+pos1[-pos2]] [file...]

Per ordinare un file usando l’intera linea come chiave

sort rubrica

Per ordinare un file usando come chiave ciò che inizia dal secondo campo

sort +1 rubrica

Per ordinare usando come chiave solo il secondo campo

sort +1 -2 rubrica

Per ordinare in ordine decrescente

sort -r file

Per ordinare interpretando il file in formato numerico

sort -n +2 -3 rubrica

E’ possibile specificare diverse opzioni:

-n ordina numericamente i campi contenenti numeri
-r ordina in senso decrescente
-tx usa il carattere specificato come separatore dei campi
-c controlla l’ordinamento alfabetico e visualizza l’output solo se non in ordine
-m fa il merge dei dati precedentemente ordinati
-u elimina le righe duplicate

uniq è un filtro, elimina le ripetizioni, usato con l’opzione -d visualizza solo le ripetizioni.

Per ordinare alfabeticamente la lista degli utenti collegati al sistema e scriverla sul file di nome list

169> cat file | sort | uniq > list
170> sort file | uniq > list
171>

find scandisce una o più directory la forma generale del comando è:

find <pathname> <expression>

ad ogni file trovato applica un insieme di test che possono comportare una serie di azioni

ogni argomento che compare in expression è un test che fornisce un risultato booleano: se il risultato della valutazione dell’argomento è vero, si esegue la valutazione dell’argomento successivo

l’operatore -a (and) fra i test è sottinteso, mentre -o (or) e ! (not) devono essere specificati esplicitamente

il comando find prevede molte opzioni utilizzabili per specificare i test nelle espressioni:

-print stampa il pathname del file considerato in quel momento (il valore di questo è sempre vero)
-name filename restituisce vero se il file corrente esaminato da find ha nome filename
-exec command
vale vero se il comando specificato restituisce 0 alla sua terminazione; al termine del comando deve esserci un ";" preceduto da "\"; se nel comando è presente un argomento { }, esso verrà sostituito, dal comando find, con il pathname del file corrente
-atime n vale vero se è stato fatto accesso al file esattamente n giorni prima; -n significa meno di n giorni, mentre +n significa più di n giorni
-ctime n vale vero se il file è stato modificato esattamente n giorni prima; -n significa meno di n giorni, mentre +n significa più di n giorni
-type char vale vero se il file è del tipo specificato in char; b corrisponde ad un file a blocchi, c a un file a caratteri, d ad una directory, f ad un file ordinario, l ad un link simbolico
-size n vale vero se il file corrente è lungo n blocchi (512 byte per blocco)
-user uname vale vero se il file appartiene all’utente specificato
-group gname vale vero se il file appartiene al gruppo specificato

Ricerca nel sottoalbero avente come radice /usr/users i file di nome doc e per ogni file trovato stampa il pathname assoluto

121> find / -name doc -print
/usr/users/valeria/doc
/studenti/sez_a/doc
122>

Ricerca nel sottoalbero avente come radice /usr/users/valeria i file ai quali è stato fatto accesso negli ultimi tre giorni e per ogni file trovato stampa il pathname assoluto

122> find /usr/users/valeria/c -atime -3 -print
/usr/users/valeria/c/main.c
/usr/users/valeria/c/libreria_1.c
123>

Per ogni file, che non sia di tipo directory dell’utente valeria, esegue il comando ls –l

123> find ~valeria ! -type d -exec ls -l {} \;
124>

Stampa il pathname assoluto dei file con dimensione minore di 10Kbyte

124> find ~valeria/doc -size -20 -print
/usr/users/valeria/doc/rel.txt
/usr/users/valeria/doc/document
125>

Cancella tutti i file che terminano con estensione .o ai quali non è stato fatto accesso da più di 7 giorni

125> find / -name ‘*.o’ -atime +7 -exec rm {} \;
126>

Esecuzione foreground e background

Normalmente l’esecuzione dei comandi avviene in foreground, in questo caso il controllo torna allo shell solo dopo la terminazione del comando.
Quando si esegue un comando in background il controllo ritorna allo shell subito dopo l’interpretazione del comando.
Per ottenere l’esecuzione background di un comando è sufficiente aggiungere il carattere & alla fine del comando stesso.

184> sort file.dat > list &
[1] 3571 + sort file.dat > list
185> lpr -p elenco
186>

Il comando ps elenca i processi dell’utente

193> ps
PID TTY STAT TIME CMD
3070 tty01 R 0:03 ps
194> find / -name core -print | lpr &
[1] 3071 3072
195> ps
PID TTY STAT TIME CMD
3071 tty01 R 0:35 find / - …
3072 tty01 S 0:00 lpr
3073 tty01 S 0:02 ps
196>

ogni processo è identificato da un numero chiamato PID (process identifier)
l’opzione ax del comando ps permette di visualizzare lo stato di tutti i processi del sistema
l’opzione l del comando ps fornisce dei dettagli ulteriori sullo stato dei processi

Il comando jobs elenca tutti i processi background dell’utente.

197>jobs -l
[1] + 3071 3072 Running find / ... | lpr
197>

Lo shell associa ad ogni comando o pipeline un numero detto job index che viene indicato tra parentesi quadre nell’output del comando job.

E’ possibile effettuare transizioni tra la modalità di esecuzione background a quella foreground e viceversa.

Per portare un processo da background a foreground

186> fg %1 oppure 186> fg
sort file.dat > list
187>

Per portare un processo da foreground a background

187> sort file.dat | lpr
^Z
Stopped
188> jobs
[1] + stopped sort lile.dat | lpr
189> bg %1 oppure 189> bg
190>

Se un job che è in esecuzione in background cerca di leggere da stdin, esso si metterà nello stato di stop. Sarà quindi necessario portarlo in foreground per permettere la lettura.

I job background possono produrre output su stdout, per impedirlo si deve dare il comando stty tostop.

Se si cerca di uscire da csh mentre ci sono job in stop verrà segnalato un warning: "You have stopped jobs".

Per attendere la terminazione di tutti i processi background si usa il comando wait

permette di visualizzare lo stato dei processi
senza parametri , elenca solo i processi dell’utente che invoca il comando

Il comando kill viene usato per inviare un segnale ad un programma, può essere usato per forzare la terminazione di un programma

il comando kill PID senza argomenti, invia il segnale 15 (Software termination) ad un processo

nel caso il processo abbia mascherato il SIGTERM è possibile uare il comando kill -9 PID che forza in ogni caso la terminazione del processo inviando il segnale 9 (Kill) che non è mascherabile o ignorabile.

197> jobs -l
[1] + 5021 Running find
[2] - 5022 Running sort
198> kill %1
[1] Killed find
199> jobs -l
[2] + 5022 Running sort
200> kill -9 5022
[2] Killed sort
201> jobs
202>

Exit status dei comandi.

Tutti i comandi definiscono un exit status il cui valore è di norma

0 se il comando è stato eseguito con successo

diverso da 0 se il comando è stato eseguito con insuccesso

Lo stato dell’ultimo comando eseguito è contenuto nella variabile shell status per visualizzarlo

echo $status

Il valore dello stato, in caso di insuccesso, può aiutare a capire il tipo di problema (consultando i manuali).

L’esecuzione di un comando può essere subordinata allo stato di terminazione del comando precedente attraverso gli operatori && e | |. Con && viene eseguito il secondo comando solo se il primo ha avuto successo, con || viene eseguito il secondo comando solo se il primo ha avuto insuccesso.

who | grep -s "valeria" | | echo "Valeria non è qui"
who | grep -s "valeria" && echo "Valeria è qui"

nel primo caso il comando echo viene eseguito solo se il comando precedente ha stato diverso da 0; nel secondo il comando echo viene eseguito solo se il comando precedente ha stato uguale a 0

grep con l’opzione -s lavora in silent mode.

... ancora comandi UNIX

grep permette di ricercare una stringa in un file (acronimo di Global Regular Expression Printer)

50> grep Rossi rubrica
Rossi Mario 02.66182363
51> grep Maria rubrica
Bianchi Maria 0321.777777
Tomasi Maria 011.555555
52> grep Rossi rubrica rubrica1
Rossi Mario 02.66182363
Rossi Lucia 011.333333
53> grep Rossi rubrica*
Rossi Mario 02.66182363
Rossi Lucia 011.333333
Rossi Ernesto 0321.111111
54> grep "Lupo Alberto" rubrica2
Lupo Alberto 0321.222222
55>

Ricerca la stringa all’inizio della riga

55> grep "^Mario" rubrica
56>

Ricerca la stringa alla fine della riga

56> grep "63$" rubrica
Rossi Mario 02.66182363
57>

Ricerca le linee che iniziano con B o con G

57> grep "^[BG]" rubrica
Bianchi Mario 01234567
Brambilla Giuseppe 09876543
Gufo Mario 024681012
58>

Ricerca le linee che non iniziano con le lettere comprese fra D e R

58> grep "^[A-CS-Z]" rubrica
oppure
58> grep "^[^D-R]" rubrica
59>

Per trovare tutte le linee che finiscono con il numero 6

grep ‘6$’ rubrica

Per trovare tutte le linee che cominciano con due caratteri alfabetici maiuscoli

grep "^[A-Z][A-Z]" rubrica

Per trovare tutte le linee che hanno numero di telefono dispari

grep ‘[13579]$’ rubrica

Per trovare le linee che non iniziano con una lettera maiuscola

grep "^[^A-Z]" rubrica
oppure
grep -v "^[A-Z]" rubrica

Per trovare tutte le linee che iniziano con numero compreso fra 10 e 99

grep "^[1-9][0-9]" file

Per trovare tutte le linee che iniziano con un numero e finiscono con & o /

grep ‘^[0-9].*[&/]$’ file

Per trovare tutte le linee che terminano con .

grep ‘\ . $’ file

Per conoscere i nomi dei file che contengono la stringa Rossi

grep - l "Rossi" rubrica.*

Per sapere in quali linee dei file specificati compare la stringa Rossi

grep -n "Rossi" rubrica.*

Per sapere quante volte compare in ogni file specificato la stringa Rossi

grep -c "Rossi" rubrica.*

awk permette di analizzare il testo come sequenza di linee separate in campi (acronimo di Aho Weinberger Kerningan), richiede che gli venga specificato un programma ed un testo da esaminare. Il programma può essere specificato sulla linea di comando o su un file.

Per ogni linea in input stampa la terza colonna

59> awk ‘{print $3}’ srcfile
oppure
59> cat > col_3
{print $3}
^d
60> awk -f col_3 srcfile
61>

Il separatore di campi di default è una qualsiasi configurazione di blank e TAB, l’opzione -F permette di specificare un separatore di campi diverso dal default

61> awk -F: ‘{print $5,$1}’ /etc/passwd
... ....
62>

il separatore è ‘:’, $5 e $1 riferiscono al quinto ed al primo campo di ogni linea; il carattere ‘,’ inserisce un o spazio fra i campi visualizzati

62> awk ‘{print $0}’ srcfile
... ... oppure
62> awk ‘{print}’ srcfile
... ... oppure
62> cat srcfile
... ....
63>

$0 riferisce all’intera linea

La forma generale di un programma awk è

pattern { action }
pattern { action }
. . . .

Ogni linea in input è testata con ogni pattern; se c’è corrispondenza viene intrapresa l’azione ad esempio

awk ‘/parola/{print}’ srcfile

in questo caso il pattern è la ricerca di parola; quando viene trovata è visualizzata l’intera linea su stdout.

Un pattern può essere una espressione regolare (vedi grep) o una condizione

awk ‘/^inizio/,/^fine/’ srcfile

il pattern è un range separato da ‘,’; se l’azione non è specificata il default è la visualizzazione su stdout

awk ‘$1 > 10{print $2}’ srcfile

converte automaticamente un campo in numero se il contesto lo richiede.

Espressioni regolari

Le espressioni regolari usano alcuni metacaratteri che sono utilizzati anche dallo shell.
Per questo motivo è necessario racchiudere fra ‘ ‘ le strighe che li contengono.

I metacaratteri utilizzati da grep sono:

[ ]   indica un elenco di alternative

.    corrisponde a "qualsiasi carattere" tranne il newline

*    corrisponde a 0 o più volte il carattere precedente

$   corrisponde a fine linea

^    fuori da [ ] indica inizio linea
     dentro a [ ] in prima posizione indica la negazione
     dentro a [ ]nelle altre posizioni è inteso come carattere

-    dentro a [ ] fra due caratteri indica il range
     dentro a [ ] in fondo alla lista viene interpretato come carattere

\    serve per interpretare il carattere successivo come tale e non come metacarattere

\<  forza la corrispondenza all’inizio di una parola

\>  forza la corrispondenza alla fine di una parola

"\<regolare\>" forza la corrispondenza sulla parola (irregolare non viene riconosciuta)

"^regolare$" forza la corrispondenza sulla linea

\{i\} ripete il carattere o l’espressione precedente i volte

\{i,j\} ripete il carattere o l’espressione precedente al minimo i volte ed al massimo j volte

\{i,\} ripete il carattere precedente almeno i volte

Ad esempio "^.\{80,\}" corrisponde a linee di almeno 80 caratteri.

Variabili di environment.

Vengono passate da un processo padre ai suoi processi figli.

si definiscono con il comando setenv

si cancellano con il comando unsetenv

il comando printenv elenca tutte la variabili di ambiente ed il loro valore

93> setenv cdir /usr/users/valeria/c
94> printenv
cdir=/usr/users/valeria/c
HOME=/usr/users/valeria
SHELL=/bin/csh
...
95> unsetenv cdir
96> printenv
HOME=/usr/users/valeria
SHELL=/bin/csh
...
97>

Variabili di environment predefinite

Vengono inizializzate nei file .login e .cshrc.

HOME contiene il pathname della home directory

PATH contiene la lista delle directory in lo shell ricerca i comandi

USER contiene il nome dell’utente

SHELL contiene il nome dello shell utilizzato dall’utente

EXINIT contiene i comandi di inizializzazione e personalizzazione per gli shell ex e vi

TERM contiene il tipo del terminale

Variabili csh predefinite

Vengono inizializzate nei file .login e .cshrc.

argv contiene i parametri posizionali

cwd contiene il full pathname della working directory

history contiene il valore della lunghezza della lista di history

ignoreeof consente di ignorare il carattere di end-of-file ‘^d’ digitato a terminale ed evita quindi una chiusura accidentale dello shell

mail indica il nome della mailbox in cui periodicamente verificata la presenza di nuovi mail; per default questo file si chiama /usr/spool/mail/$USER

noclobber impedisce la scrittura attraverso la redirezione dello standard output su un file già esistente

notify permette la segnalazione asincrona della terminazione di processi in background prompt contiene la stringa da utilizzare come shell prompt

savehist contiene il valore della lunghezza della lista di history da salvare al termine di una sessione

status contiene lo stato di terminazione dell’ultimo comando eseguito

 

Elenco comandi UNIX

alias e unalias
awk
cat
cd
cp
csh
date
echo
find
grep
head
history
kill
ls
man
mkdir
mv
pwd
ps
rm
rmdir
sort
tail
uniq
wc
who
who am i
whoami

Funzioni built-in

Csh ridefinisce alcuni comandi UNIX con proprie funzioni built-in. Ad esempio alcuni comandi ridefiniti sono:

jobs
fg
bg

Consultare il manuale on line del comando csh per dettagli ulteriori ( man csh ).

Valeria Gusulfino
valeria@fauser.edu