Ancora sulla shell
Shell e comandi
• La shell e' un programma che interpreta i comandi
dell'utente.
• I comandi possono essere dati da terminale, oppure
contenuti in file testo (detto script), che viene letto ed
eseguito dalla shell.
• Una shell puo' essere:
– di login,
– interattiva
Shell di login
• La shell di login viene attivata automaticamente al login nel sistema.
• Interpreta prima di tutto uno script uguale per tutti gli utenti e scritto
dal sistemista: /etc/profile.
• Successivamente esegue uno script definito dall'utente, nella propria
home directory. Per la bash, esegue solo il primo script fra:
~/.bash_profile, ~/.bash_login, ~/.profile
• Inoltre, anche alla sua attivazione la shell esegue automaticamente lo
script ~/.bashrc.
• All'uscita della sessione viene eseguito lo script ~/.bash_logout
Nota: ~ indica la home directory
Shell Script
• Uno script e' dunque una lista di comandi Unix o di shell.
I comandi sono separati da operatori (es ; = sequenza) o da un fine
linea.
• Se non specificato altrimenti si suppone che sia la shell sh (che in
Linux e' identificata con bash) ad interpretarli.
• Se si vuole utilizzare un altra shell, si indica sulla prima linea:
#! /bin/tcsh
….
• Il carattere "#" in prima colonna, senza "!" dopo indica una riga di
commento.
Esecuzione script
Ci sono almeno due modi per eseguire uno script:
1. Dandone semplicemente il nome, con eventuali argomenti
In questo caso viene attivata una nuova shell (sh, tcsh, ksh o altro,
come indicato nella prima linea dello script) che esegue i comandi
dello script e poi termina.
Lo script deve essere marcato "eseguibile" attraverso il comando
chmod.
1.
attraverso il comando source (abbreviato anche con il carattere ".")
seguito dal nome dello script. In questo caso i comandi sono eseguiti
all'interno della shell corrente.
Comandi
Ci sono vari tipi di comandi:
• Comandi interni o di shell. Sono comandi eseguiti internamente alla
shell, come cd, pwd.
• Comandi esterni. Sono programmi, ad esempio comandi Unix, esterni.
• Alias. E' possibile rinominare i comandi, cambiando anche il modo di
passare parametri.
• Funzioni. Negli script sono definibili delle funzioni (vedi manuale).
Variabili
• E' possibile assegnare delle variabili di tipo stringa di caratteri, poi
riferibili nella stessa shell.
• Una variabile e' assegnata con lo statement name=value
• L'assegnazione e' valida solo nella shell in cui e' eseguita, ma puo'
essere esportata nelle shell di livello inferiore (cioe’ creata con
um’operazione dalla shell corrente) con il comando di shell
• $name denota il valore corrente della variabile name.
Alcune variabili predefinite
Predefinite ed assegante
PPID parent del processo
PWD current working directory
UID user ID
EUID effective user ID
Predefinite, non assegnate
PATH pathname fra cui cercare i comandi (* ).
HOME home directory del current user
(*) Quando si da' un comando la shell ricerca il file eseguibile nelle
directory indicate nella variabile PATH.
Pipeline
• Una pipeline e' un comando o una sequenza di comandi separati da "|".
•
In questo caso l'output di un comando e' preso come input dal
successivo.
• Considerate ad esempio I due comandi:
– ls –al : mostra su standard output il contenuto della directory (ogni linea =
corrisponde ad un file)
– grep word: legge linee da standard input e mostra su standard output le
linee dove compare la stringa word
• Allora la pipeline ls –al | grep –n bash seleziona dall’output di ls gli
attributi dei file con nome che contiene la stringa bash
Lista
Una lista e' una sequenza di pipeline separati da un operatore fra
;
i comandi sono eseguiti in sequenza
&
i comandi che precedono questo carattere vengono messi
in esecuzione in background
&&
operatore booleano and: se il primo comando ha successo,
si va avanti nell'esecuzione, altrimenti si termina la lista
||
operatore booleano or: se il comando a sinistra a successo
a sinistra e' vero, non si prosegue, altrimenti si va avanti con
esecuzione
Esempio di sequenza “;”
• La lista
ls –al ; cd .. ; ls –al
esegue in sequenza i tre comandi (lista dir
corrente, spostamento dir genitore, lista dir
genitore)
• La lista
ls –al ; grep bash
esegue prima ls –al e poi grep bash (cioe’ attende
l’input da tastiera)
(Notate la differenza con ls –al | grep bash)
Esempio di esecuzione in background &
• L’operatore & serve per eseguire comandi in background ovvero la
shell corrente non aspetta la terminazione della subshell che esegue il
comando (vengono eseguite in parallelo)
• E’ utile per eseguire operazioni “costose” senza dover aspettare i
risultati per proseguire
• Ad esempio, il comando
find / –name giorgio
cerca il file di nome giorgio in tutto il file system (cioe’ a partire da /)
• La lista
find / –name giorgio > res & ls –al
lancia in background la ricerca salvando il risultato nel file res;
la shell prosegue subito l’esecuzione lanciando il comando ls -al
Liste ed exit status
• Ogni comando restituisce un exit status (valore di ritorno)
• Un comando che ha avuto successo restituisce 0, mentre, in caso di
insuccesso, viene restituito un valore diverso da zero, che solitamente
può essere interpretato come un codice d'errore.
• Comandi, programmi e utility UNIX correttamente eseguiti
restituiscono come codice di uscita 0, con significato di successo
• In maniera analoga, sia le funzioni all'interno di uno script che lo script
stesso, restituiscono un exit status che nient'altro è se non l'exit status
dell'ultimo comando eseguito dalla funzione o dallo script.
• In uno script, il comando exit nnn può essere utilizzato per inviare
l'exit status nnn alla shell (nnn deve essere un numero decimale
compreso nell'intervallo 0 - 255).
Esempio di lista con &&
• Considerate la lista
comando-1 && comando-2 && … && comando-n
• Ogni comando che a turno deve essere eseguito si accerta che
quello precedente abbia restituito come valore di ritorno true
(=valore zero).
• Alla prima restituzione di false (=valore non-zero), la serie dei
comandi termina (il primo comando che ha restituito false è
l'ultimo che è stato eseguito).
• Esempio:
grep giorgio .bashrc && echo “Trovato”
• Stampa su video “Trovato” solo se .bashrc contiene occorrenze
della stringa “giorgio”
Esempio lista con ||
• Considerate la lista
comando-1 || comando-2 || … || comando-n
• Ogni comando che a turno deve essere eseguito si accerta che
quello precedente abbia restituito false. Alla prima restituzione
di true, la serie dei comandi termina (il primo comando che ha
restituito true è l'ultimo che è stato eseguito).
• Esempio:
grep giorgio .bashrc && echo “Non trovato”
• Stampa su video “Trovato” solo se .bashrc contiene occorrenze
della stringa “giorgio”
Comando TEST
• Il comando test e' usato per definire condizioni su proprieta' dei file, o
uguaglianza di stringhe (non valori numerici).
• Il comando test expr puo' anche essere scritto come: [ expr ]
•
test -d file oppure [ -d file ]
test -f file oppure [ -f file ]
test -e file oppure [ -e file ]
test -L file oppure [ -L file ]
test -r file oppure [ -r file ]
test -x file oppure [ -x file ]
•
test stringa1 = stringa2 oppure [ stringa1 = stringa 2 ] vero se uguali.
test stringa1 != stringa2 oppure [ stringa1 != stringa2 ] vero se diverse
vero se file esiste ed e' una directory.
vero se il file esiste ed e' un file di dati.
vero se il file esiste.
vero se il file esiste ed e‘ un link simb.
vero se il file esiste ed e' leggibile.
vero se il file esiste ed e' eseguibile.
Esempi Test
• Il comando test confronto (oppure [ confronto ]) restituisce un exit
status corrispondente al risultato del confronto (0 per vero, 1 per falso).
• Esempi:
–
–
–
–
–
–
–
[ -w giorgio ] && echo “il file giorgio ha il diritto di scrittura”
[ -Z pippo ] && echo “sono il proprietario del file pippo”
[ -z “” ] && echo “la stringa ha lunghezza zero”
[ -n “ “] && echo “la stringa ha lunghezza > zero”
[ “aaa” = “bbb” ] && echo “stringhe uguali”
[ 2 –eq 2 ] && echo “numeri uguali”
[ 2 –lt 3 ] && echo “minore di”
• Attenzione agli spazi: [-w giorgio] restituisce un errore
[[ … ]] vs [… ]
• La bash fornisce anche un comando di verifica estesa
[[ … ]] che ha caratteristiche piu simili ai test nei linguaggi di
programmazione
• Ad es. dentro [[ … ]] non viene eseguita l’espansione dei nomi di file
con caratteri jolly tipo *)
• Esempio
– [ -e *.sh ] ha successo se esiste un file con estensione .sh
– [[ -e *.sh ]] fallisce
Operatore (( … ))
• L’operatore (( … )) viene utilizzato per
valutare espressioni aritmetiche (numeri
interi)
• Ad esempio
– (( 3 + 2 > 1 )) && echo “ok”
– (( 10 + 1 )) && echo “valore > zero”
Parametri script
• I comandi usualmente hanno dei parametri passati
come argomenti al momento dell’invocazione
• Ad esempio:
grep giorgio .bashrc
ha come argomenti giorgio e .bashrc
• La shell usa delle variabili speciali per accedere
agli argomenti
Parametri posizionali
• Sono i parametri della chiamata ad uno script.
• Si identificano con il carattere $ seguito dall'indice della
posizione. Se si usano numeri di 2 cifre, si racchiudono fra
parentesi graffe.




$0 nome dello script.
$1 primo argomento passato dalla command-line
$2 secondo argomento
….
• Esempio
nome_script alfa
$0
$1
10
$2
Parametri speciali
 $@ collezione di tutti i parametri (a partire da
$1).
 $* stringa ottenuta concatenando tutti i
parametri in un'unica stringa (normalmente
separati da uno spazio).
Quindi "$*" indica "$1 $2 $3 .. $n".
 $# numero di parametri presenti.
 $$ process id della shell.
 $- flag opzionali.
Espansione nella Shell
La shell esegue diversi tipi di espansione
Espansione dei nomi di file con caratteri jolly (*,?,[..])
• Una stringa con caratteri jolly viene espansa
nella lista di nomi di file che fanno matching con il pattern
di partenza
• Ad esempio in ls –al *.sh *.sh viene espansa con la lista di
nomidi file con estension .sh
• Tipo speciale di espressioni regolari che dipendono dal
contesto in cui si valutano
Espansione
Espansione variabili
• Abbiamo visto che la shell sostitusce l’espressione $nomec
con il valore corrente della variabile nome
Sostituzione dei comandi.
• L’operatore
$( command-list ) oppure ` command-list`
esegue command-list e rimpiazza il tutto con il suo output.
Espansione
• Espressioni aritmetiche
(( espressione ))
• si rimpiazza l’espressione con il risultato della
valutazione di espressione (operatori: numeri
interi, +, *,…)
Comando FOR
for name [ in word; ] do list; done
dove name e word sono stringhe di caratteri.
word e‘ scritto usando una grammatica regolare (di cui si e'
gia' parlato a proposito di identificatori di file) e genera un
insieme di elementi (stringhe di caratteri).
name (una variabile) assume uno alla volta ognuno dei valori
di word, e ogni volta e' eseguito list.
Esempi For
for file in *.old
do
newf=`basename $file.old`
cp $file $newf.new
done
basename estrae il nome di base (senza path)
Comando CASE
case word in [pattern [ | pattern ] [....] list ;; ] ... esac
dove
word e' espanso, ottenendo una stringa.
Se fa il match con uno degli elementi indicati come pattern,
viene eseguita la lista collegata, poi termina il comando.
Se no, esce con status=0.
Esempi CASE
case $1 in
aa|ab) echo A ;;
b?) echo B ;;
c*) echo C ;;
*)
echo D ;;
asec
| alternativa nei casi
*=qualsiaisi stringa, ?=un carattere qualsiasi
Comandi while e until
• while list do list done
• Il comando while esegue "do list " finche' l'ultimo
comando di "list " ritorna status=0
• until list do list done
• Come while ma con il test negato.
Esempio WHILE
while [ $# -gt 0 ]
do
echo $1
shift
done
shift sposta i parametri verso sinistra
Comando IF
• if list then list [ elif list the list ] ... [ else list ] fi
• Si esegue "if list ", se lo status di ritorno e' =0
allora viene eseguito "then list ".
• Altrimenti si esegue "else list ", oppure gli altri "if
" annidati.
Esempi IF
#! /bin/bash
# prova-if
if [ $# -ge 2 ]
then echo $2
elif [ $# -eq 1 ]; then echo $1
else
echo No input
fi
Allora:
./prova-if
./prova-if a
./prova-of a b c
scrive No input
scrive a
scrive b
Esempi Scripting
#! /bin/sh
echo -n "stringa ? "
read VAR
case $VAR in
"A" | "B" | “C" )
echo maiuscolo;;
“a" | “b" | “c" )
echo minuscolo ;;
*)
echo altro ;;
esac
Esempi Script
ESEMPIO
#! /bin/bash
# script di login
if [ "$LOGNAME" = "root" ]; then
echo " Welcome dear $LOGNAME"
if [ -f $HOME/hello]; then
echo $HOME/hello
fi
fi
Nota: # [ -f …] = test –f
Quoting
• ‘…’ : Tutto quanto e' racchiuso fra gli apici e' preso come
carattere semplice (escluso il carattere apice stesso). Non e'
quindi fatta nessuna espansione.
• “…”: Come con il carattere precedente, ma con delle
eccezioni. Viene fatta l'espansione dei parametri
(interpretazione del carattere $), viene fatta la command
substitution, si considera il carattere di escape "\".
Esempi
#! /bin/bash
echo "numero argomenti = $#"
for i in $* do
echo "argomento $i"
done
#! /bin/bash
# script s1
VAR=`ls`
# espansione comando ls: lista corta di tutti
echo VAR=$VAR
for i in $VAR; do
ls -ld $i;
done
Comandi built-in
alias
Crea degli alias per I nomi di comandi
kill
Termina processi
echo
Output argomenti separati da blank. Ritorna 0.
exec [ [ - ] command [ arguments ] ]
Esegue il comando nella shell corrente.
exit [ n ]
Exit dallashell con status = n.
read name1 name2…
Legge una linea dallo standard input: la prima word e‘ assegnata al primo name e cosi' via.
read name1 name2…
Legge una linea dallo standard input: la prima word e‘
assegnata al primo name e cosi' via.
Scarica

PPT - DISI