...

script

by user

on
Category: Documents
25

views

Report

Comments

Description

Transcript

script
Shell Scripting
Versione riveduta, corretta, ed estesa 15 ottobre 2008
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 o 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
Script
• Uno script e' dunque una lista di comandi Unix o di shell.
I comandi sono separati da operatori 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.
Es. per usare tcsh:
#! /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.
2. 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
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’ create con un’operazione dalla shell corrente)
con il comando di shell export
• $name denota il valore corrente della variabile name.
Alcune variabili predefinite
Predefinite ed assegnate
PWD current working directory
UID user ID
PS1 testo mostrato nel prompt
Predefinite, non assegnate
PATH pathname fra cui cercare i comandi (* ).
HOME home directory dell’utente corrente
(*) Quando si da' un comando la shell ricerca il file eseguibile nelle
directory indicate nella variabile PATH.
Esempi comandi
source .bashrc (oppure . .bashrc)
esegue comandi in .bashrc nella shell corrente (ad esempio
dopo modifiche)
echo $HOME
mostra valore della variabile HOME
export PS1=“\u:\w> “
cambia il prompt (vedi manuale bash, sez. prompting)
Esempio script
• Salvo in un file mycom.sh:
#! /bin/bash
echo $HOME
• Poi aggiungo diritto esecuzione
chmod +x mycom.sh
• Infine eseguo lo script
./mycom.sh
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
Liste di comandi
Una lista e' una sequenza di pipeline separati da:
;
i comandi sono eseguiti in sequenza (se un comando fallisce si
prosegue nell’esecuzione dei comandi seguenti)
&
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
find / –name giorgio
cerca il file di nome giorgio in tutto
il file system (cioe’ a partire da /)
find / –name giorgio > res & ls –al
lancia in background la ricerca salvando in res;
la shell prosegue subito l’esecuzione lanciando il comando ls -al
Exit status
• Ogni comando restituisce un exit status (valore di ritorno)
• Un comando che ha successo restituisce 0, altrimenti un
codice di errore diverso da 0
• Comandi, programmi e utility UNIX correttamente eseguiti
restituiscono come codice di uscita 0, con significato di
successo
• Sia le funzioni all'interno di uno script che lo script stesso
restituiscono un exit status = exit status dell'ultimo
comando eseguito
• Il comando exit N può essere utilizzato definire l’exit
status N in [0-255] da inviare alla shell
Esempio di lista con &&
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(=0)
• Alla prima restituzione di false (=/=0), la serie dei comandi
termina (il primo comando che ha restituito false è l'ultimo
che è stato eseguito).
grep giorgio .bashrc && echo “Trovato”
Stampa su video “Trovato” solo se .bashrc contiene
occorrenze della stringa “giorgio”
Esempio lista con ||
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).
grep giorgio .bashrc || echo “Non trovato”
Stampa su video “Non trovato” solo se .bashrc non
contiene occorrenze della stringa “giorgio”
Test: [ ... ]
Il comando test expr oppure [ expr ] e' usato per definire
condizioni su proprieta' dei file e uguaglianza di stringhe
(non valori numerici).
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 ]
[ stringa1 = stringa 2 ]
[ stringa1 != stringa2 ]
il file esiste ed e' una directory.
il file esiste ed e' un file di dati.
il file esiste.
il file esiste ed e‘ un link simb.
il file esiste ed e' leggibile.
il file esiste ed e' eseguibile.
vero se uguali
vero se diverse
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 ”” ] && 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 *
[ -e *.sh ] ha successo se esiste un solo file con estensione .sh
[ -e *.sh ] fallisce se esistono piu’ file con estensione .sh
(too many arguments)
[ -e “*.sh” ] fallisce
[[ -e *.sh ]]
fallisce
(( … ))
Il comando (( … )) viene utilizzato per valutare espressioni
aritmetiche (numeri interi)
(( 3 + 2 > 1 )) && echo ”ok”
(( 10 + 1 )) && echo ”valore > zero”
(( x=10+1 )) && echo $x
(( x=0 )) | | echo $x
Per usare float e funzioni piu sofisticate occorre usare
programmi esterni come “bc”
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
Espansione dei pattern
• Un pattern 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
Espansione variabili
• Abbiamo visto che la shell sostitusce l’espressione $nomec
con il valore corrente della variabile nome
Espansione
Sostituzione dei comandi.
$( command-list ) oppure `command-list`
• esegue command-list e rimpiazza il tutto con il suo output
Espressioni aritmetiche
$(( espressione ))
• rimpiazza l’espressione con il risultato della valutazione
dell’espressione (operatori: numeri interi, +, *,…)
Costrutti condizionali e cicli
• La shell interpreta costrutti simili a quelli del C: if, case,
for, while
• In tutti gli esempi di costrutti che vedremo i ritorno a capo
sono necessari, nel caso in cui si voglia autilizzare una sola
riga, vanno sostituiti con ; (punto e virgola).
• Useremo nel segue le parentesi quadre nella sintassi di un
comando per indicare una parte opzionale
If-then-else
if test
then
commands
[elif test ; then commands]
[else commands]
fi
Esempio
if [ $# -ge 2 ]
then echo $2
elif [ $# -eq 1 ]; then echo $1
else echo No input
fi
Allora:
./prova-if
scrive No input
./prova-if a
scrive a
./prova-of a b c
scrive b
Case
case word in
pattern [| pattern]...) commands
;;
pattern [| pattern]...) command
;;
...
esac
Nota: [ | pattern ] = | pattern opzionale
Esempio
case $( uname -m ) in
i[3456]86 ) echo "Intel o simili";;
alpha )
echo "Alpha";;
arm )
echo "Arm";;
* )
echo "Altro";;
esac
Pattern i[3456]86: i386 i486 i586 i686
Ciclo for classico
for (( i=0 ; i<MAX ; i++ ))
do
commands
done
Ciclo su una lista
for name [ in words ... ]
do
commands
done
Nota: [ in words ... ] parte opzionale
Esempio For
for file in *.old
do
cp $file copy_$file
done
Per ogni file A nella directory corrente crea una
copia copy_A
Cicli while e until
while test
do
commands
done
until test
do
commands
done
Esempio WHILE
while [ $# -gt 0 ]
do
echo $1
shift
done
shift sposta i parametri verso sinistra
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 ”No. arg = $#”
for i in $* do
echo ”argomento
$i”
done
#! /bin/bash
VAR=`ls`
echo VAR=$VAR
for i in $VAR; do
ls -ld $i;
done
Array
• Si possono usare array mondimensionali di dim.
arbitraria (indici 0,1,...)
• Si dichiarano con:
declare –a myarray
oppure si inizializzano direttamente:
myarray=(a 1 b 3 4)
• Si usa poi la sintassi
myarray[expr]=... e ${myarray[expr]}
Esempio uso array
i=0
declare -a A
for file in ./config/*
do
A[$i]=$file
echo ”${A[$i]}” #stampa A[i]
(( i++ ))
done
echo ”${#A[*]}”
#stampa no. elementi A
Fly UP