63
1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell (bash). Sicuramente la shell più popolare è “bash”. Bash è la shell che è stata introdotta nel sistema operativo GNU. Bash è una shell sh- compatibile che incorpora utili caratteristiche della Korn shell (ksh) e della C shell (csh). Bash è conforme allo standard IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools. Garantisce miglioramenti funzionali rispetto a sh sia per programmare che per l’uso interattivo.

1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

Embed Size (px)

Citation preview

Page 1: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.1

La shell di Linux Linux ha una varietà di shell differenti:

Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell (bash).

Sicuramente la shell più popolare è “bash”. Bash è la shell che è stata introdotta nel sistema operativo GNU. Bash è una shell sh-compatibile che incorpora utili caratteristiche della Korn shell (ksh) e della C shell (csh).

Bash è conforme allo standard IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools.

Garantisce miglioramenti funzionali rispetto a sh sia per programmare che per l’uso interattivo.

Page 2: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.2

Programming o Scripting ? Bash non è soltanto un’eccellente interprete di comandi, ma

un vero e proprio supporto per un linguaggio di script. Il linguaggio di script della shell permette di utilizzare le potenzialità della shell e di automatizzare un mucchio di compiti che richiederebbero altrimenti una grande quantità di comandi.

Differenza tra linguaggi di programmazione e linguaggi di script: I linguaggi di programmazione sono in genere notevolmente più

potenti e veloci dei linguaggi di script. I linguaggi di programmazione generalmente partono dal codice sorgente e vengono compilati in un eseguibile. Tale eseguibile non è facilmente portabile su differenti sistemi operativi.

Un linguaggio di script parte a sua volta dal codice sorgente, ma non viene compilato in un eseguibile. Piuttosto, un interprete legge le istruzioni nel file sorgente ed esegue ciascuna istruzione. I programmi interpretati sono in genere più lenti dei programmi compilati. Il vantaggio principale è che si può facilmente portare il file sorgente su ogni sistema operativo. Bash è un linguaggio di script. Altri esempio di linguaggi di script sono Perl, Lisp, e Tcl.

Page 3: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.3

Il primo programma bash Occorre sapere come usare un editor di testo. Ci

sono due editor di testo principali in Linux: vi (o vim), emacs (o xemacs).

Dunque lanciamo un editor di testo; ad esempio: $ vi &

e digitiamo ciò che segue: #!/bin/bashecho “Hello World”

La prima linea dice a Linux di utilizzare l’interprete bash per eseguire questo script. Lo chiameremo hello.sh. Ora rendiamo lo script eseguibile: $ chmod 700 hello.sh $ ls –l-rwx------ hello.sh

Page 4: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.4

Il primo programma bash Per eseguire il programma:

$ hello.sh

-bash: hello.sh: command not found

La directory home (in cui il comando hello.sh si trova)

non si trova fra quelle elencate nella variabile d’ambiente PATH echo $PATH

:bin:/usr/bin:…

Occorre specificare il path di hello.sh $/home/srinaldi/Scripts/hello.sh $./hello.sh

Page 5: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.5

Il secondo programma bash Scriviamo un programma che copia tutti i files in una

directory, e poi cancella la directory con tutto il suo contenuto. Ciò può essere fatto col seguente comando: $ mkdir trash

$ cp * trash$ rm -rf trash

Invece di essere costretti a digitare tutto ciò in modo interattivo nella shell, scriviamo uno script di shell: $ cat > trash

#!/bin/bash# this script deletes some files

mkdir trash

cp * trashrm -rf trash

echo “Deleted all files!”

Page 6: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.6

Variabili Si possono usare le variabili come in ogni linguaggio di

programmazione. I loro valori sono sempre memorizzati come stringhe, ma ci sono delle strutture nel linguaggio di shell che convertono le variabili in numeri per fare i calcoli.

Non c’è bisogno di dichiarare una variabile, il solo fatto di assegnarle un valore la crea automaticamente.

Esempio #!/bin/bash

STR=“Hello World!”

echo $STR

La linea 2 crea una variabile detta STR e assegna la stringa "Hello World!" ad essa. Quindi il valore di questa variabile viene recuperato mettendo il '$' all’inizio.

Page 7: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.7

Attenzione!

Il linguaggio della shell non tipizza (assegna un tipo a) le variabili. Ciò significa che una variabile può contenere dati numerici o alfabetici. count=0 count=Sunday

Cambiare il tipo di una variabile può generare confusione, sia per chi scrive lo script che per qualcuno che cerca di modificarlo, pertanto è raccomandato l’uso di un solo tipo di dati per ogni singola variabile all’interno di uno script.

\ è il carattere di escape di bash, e conserva il valore letterale del carattere che segue. $ ls \*

ls: *: No such file or directory

Page 8: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.8

Virgolette singole e doppie

Quando si assegnano dati contenenti spazi o caratteri speciali, i dati devono essere racchiusi tra virgolette (singole o doppie).

Quando si usano virgolette doppie (partial quoting) per stampare a video una stringa di caratteri, ogni variabile verrà sostituita dal valore che essa assume in quel momento. $ var=“test string”

$ newvar=“Value of var is $var”$ echo $newvarValue of var is test string

L’uso di virgolette singole (full quoting) per visualizzare una stringa di caratteri non permette la risoluzione delle variabili. $ var=’test string’

$ newvar=’Value of var is $var’$ echo $newvarValue of var is $var

Page 9: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.9

Esempi vari

$ pippo= pluto $ pippo =pluto

$ ls [Pp]* $ ls “[Pp]*” $ ls ‘[Pp]*’

$ var=“’(]\\{}\$\”” $ echo $var $ echo “$var” $ echo ‘$var’

$ echo \z # z $ echo \\z # \z $ echo ‘\\z’ # \\z

errore

Not resolved

Page 10: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.10

Esempi vari

$ pippo=cat

$ echo “comando = \” $pippo \” “

comando =“ cat ”

$ echo ‘comando = \” $pippo \” ‘

comando =\” $pippo \”

$ echo ‘comando = ” $pippo ” ‘

comando =” $pippo “

Page 11: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.11

Il comando export Il comando export inserisce una variabile nell’ambiente, così che essa sarà

accessibile ai processi figli. Per esempio: $ x=hello

$ bash # Run a child shell.

$ echo $x # Nothing in x.

$ exit # Return to parent.

$ export x

$ bash

$ echo $x

hello # It's there. Se il processo figlio modifica x, non verrà modificato il valore originale nel

processo padre. Si verifichi tale fatto cambiando x nel modo seguente: $ x=ciao

$ exit

$ echo $x

hello

Page 12: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.12

Variabili di ambiente Ci sono due tipi di variabili:

Variabili locali Variabili di ambiente

Le variabili di ambiente sono definite a livello di sistema e possono di norma essere reperite usando il comando env. Le variabili di ambiente contengono valori speciali. Ad esempio, $ echo $SHELL/bin/bash$ echo $PATH/usr/X11R6/bin:/usr/local/bin:/bin:/usr/bin

Le variabili di ambiente sono definite in /etc/profile, /etc/profile.d/ e ~/.bash_profile. Questi files sono files di inizializzazione e vengono letti quando la shell bash viene invocata. Al momento del logout da parte dell’utente, bash legge ~/.bash_logout.

Page 13: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.13

Variabili di ambiente HOME: Il pathname della home dell’utente

(l’argomento di default di cd). PATH: Il “search path” per i comandi. É un elenco

delle directories (separate da :) nelle quali la shell cerca il comando da eseguire.

Solitamente, si lancia uno script nel modo seguente: $ ./trash.sh

Ponendo PATH=$PATH:. la nostra working directory viene inclusa nel “search path” per i comandi, e possiamo digitare semplicemente: $ trash.sh

Page 14: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.14

Variabili di ambiente

LOGNAME: contiene il nome dell’utente. HOSTNAME: contiene il nome della macchina. MACHTYPE: hardware del sistema. PS1: sequenza di caratteri visualizzata davanti al prompt.

\t ora \d data \w current directory \W ultima parte della current directory \u nome dell’utente \$ carattere del promptEsempio[lferrari@homelinux lferrari]$ PS1=‘ciao \u *’ciao lferrari* _

UID: contiene l’id number dell’utente (non può essere cambiato).

Page 15: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.15

Il comando exit

Il comando exit può essere usato per terminare uno script. Esso restituisce un valore, che è disponibile per il processo padre dello script. Quando uno script termina col comando exit

senza ulteriori parametri, lo stato di uscita è lo stato di uscita dell’ultimo comando eseguito nello script.#!/bin/bash

COMMAND_1

. . .

# exit with status of last command. COMMAND_LAST

exit

#!/bin/bash

COMMAND_1

. . .

# exit with status of last command. COMMAND_LAST

exit $?

Page 16: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.16

Il comando exit

Il comando exit può essere usato per terminare uno script. Esso restituisce un valore, che è disponibile per il processo padre dello script. Quando uno script termina con

exit nnn

dove nnn=0-255, lo stato di uscita è nnn.

Page 17: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.17

Il Comando read

Il comando read consente di leggere l’input da tastiera e memorizzarlo in una variabile.

Esempio (read.sh)

Page 18: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.18

Il Comando read

Opzioni read –s (non stampa a video l’input) read –nN (accetta soltanto N caratteri di input) read –p “message” (visualizza il messaggio

“message”) read –tT (accetta l’input per T secondi)

Esempio$ read –s –n1 -p “Yes (Y) or not (N)?” answerYes (Y) or not (N) ? (digitare Y: non si vedrà)

$ echo $answer

Y

Page 19: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.19

Sostituzione dei comandi La “virgoletta retrograda”, o accento grave, “`” è diversa

dalla virgoletta “´”. Essa viene usata per la sostituzione dei comandi: `command` $ LIST=`ls`$ echo $LISThello.sh read.sh

PS1=“`pwd`>”/home/rinaldi/didattica/>

Possiamo eseguire la sostituzione dei comandi anche usando $(command) $ LIST=$(ls)$ echo $LISThello.sh read.sh

rm $( find / -name “*.tmp” ) ls $( pwd ) ls $( echo /bin )

Page 20: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.20

Esempio

$ a=`echo Hello`

$ echo $a

$ echo ‘$a’

$ b=`ls /home`

$ echo $b

$ echo $a $b

$ echo “$a $b”

Page 21: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.21

Operatori aritmetici

+ somma

- sottrazione

* moltiplicazione

/ divisione

** esponenziazione

% modulo

Esempio$ a=(5+2)*3

$ echo $a

$ b=2**3

$ echo $a+$b

Page 22: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.22

Valutazioni aritmetiche Il costrutto let può essere usato per creare funzioni

matematiche $ let X=10+2*7$ echo $X24$ let Y=X+2*4 $ echo $Y32

Un’espressione aritmetica può essere valutata usando $[expression] o $((expression)) $ echo $((123+20))143

$ VALORE=$[123+20] $ echo $[10*$VALORE]1430

$ echo $[2**3] $ echo $[8%3]

Non è necessario usare $X per riferirsi al valore di X

Page 23: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.23

Costrutti condizionali Le strutture condizionali ci permettono di decidere

se eseguire un’azione oppure no, a seconda del valore di un’espressione da valutare. Il costrutto condizionale fondamentale è: if [ expression ];

thenstatements

elif [ expression ]; then statements

else statements

fi Le parti elif (else if) e else sono opzionali.

Page 24: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.24

Espressioni Un’espressione può essere: un confronto fra stringhe, un

confronto fra numeri, un operatore su file, un operatore logico ed è rappresentata da [ expression ]:

Confronto fra stringhe: = per valutare se due stringhe sono uguali != per valutare se due stringhe sono diverse -n per valutare se la lunghezza di una stringa è maggiore di

zero -z per valutare se la lunghezza di una stringa è uguale a zero

Esempi: [ s1 = s2 ] (vero se s1 è uguale a s2, altrimenti falso) [ s1 != s2 ] (vero se s1 è diverso da s2, altrimenti falso) [ s1 ] (vero se s1 è non vuota, altrimenti falso) [ -n s1 ] (vero se s1 ha lunghezza maggiore di 0, altrimenti

falso) [ -z s2 ] (vero se s2 ha lunghezza 0, altrimenti falso)

Page 25: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.25

Espressioni Confronto fra numeri:

-eq valuta se due numeri sono uguali -ge valuta se un numero è maggiore o uguale a un altro -le valuta se un numero è minore o uguale a un altro -ne valuta se due numeri sono diversi -gt valuta se un numero è maggiore di un altro -lt valuta se un numero è minore di un altro

Esempi: [ n1 -eq n2 ] (vero se n1 è uguale a n2, altrimenti falso) [ n1 -ge n2 ] (vero se n1 è maggiore o uguale a n2, altrimenti

falso) [ n1 -le n2 ] (vero se n1 è minore o uguale a n2, altrimenti

falso) [ n1 -ne n2 ] (vero se n1 è diverso da n2, altrimenti falso) [ n1 -gt n2 ] (vero se n1 è maggiore di n2, altrimenti falso) [ n1 -lt n2 ] (vero se n1 è minore di n2, altrimenti falso)

Page 26: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.26

Espressioni Operatori su files:

-d controlla se il cammino dato rappresenta una directory -f controlla se il cammino dato rappresenta un file ordinario -e controlla se il nome del file esiste -s controlla se un file ha lunghezza maggiore di 0 -r controlla se si possiede il permesso di lettura per un file o una directory -w controlla se si possiede il permesso di scrittura per un file o una directory -x controlla se si possiede il permesso di esecuzione per un file o una

directory Esempi:

[ -d fname ] (vero se fname è una directory, altrimenti falso) [ -f fname ] (vero se fname è un file ordinario, altrimenti falso) [ -e fname ] (vero se fname esiste, altrimenti falso) [ -s fname ] (vero se la lunghezza di fname è maggiore di 0, altrimenti

falso) [ -r fname ] (vero se fname ha il permesso di lettura, altrimenti falso) [ -w fname ] (vero se fname ha il permesso di scrittura, altrimenti falso) [ -x fname ] (vero se fname ha il permesso di esecuzione, altrimenti falso)

Page 27: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.27

Esempio #!/bin/bashif [ -f /etc/fstab ];then

cp /etc/fstab .echo “Done.”

elseecho “This file does not exist.”exit 1

fi Esercizio. Scrivere uno script di shell che prenda in input un

nome di file <pippo>: Lo script controlla se esiste una cartella Backup, altrimenti la crea. Se il file cercato esiste, copia il file con lo stesso nome + .bak nella

cartella Backup. Se il file non esiste, allora visualizza il messaggio “The file <pippo>

does not exist!!!”

Page 28: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.28

Espressioni

Operatori logici:! negare (NOT) un’espressione logica-a congiunzione (AND) tra due espressioni

logiche-o disgiunzione (OR) tra due espressioni logiche

Page 29: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.29

Espressioni

Operatori logici:&& congiunzione (AND) tra due espressioni

logiche|| disgiunzione (OR) tra due espressioni logiche

Page 30: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.30

Parametri di shell Un parametro posizionale corrisponde ad un argomento

fornito alla shell al momento dell’esecuzione di un programma. Il primo argomento specificato corrisponde alla variabile 1, il secondo argomento alla variabile 2 e così via. Il parametro posizionale “N” può essere referenziato come “${N}”, o come “$N” quando “N” consiste in una singola cifra.

Parametri speciali $# è il numero dei parametri passati $0 rende il nome dello script di shell in esecuzione nonchè la sua

posizione nel file system $* rende una singola parola contenente tutti i parametri passati allo

script $@ rende un array di parole contenente tutti i parametri passati allo

script

Page 31: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.31

Il costrutto case Viene usato per eseguire azioni basate su valori specifici.

Usato spesso al posto di un costrutto if se c’è un numero elevato di condizioni. Il valore usato può essere un’espressione. Ciascun insieme di azioni deve concludersi con una coppia di punto

e virgola. Il simbolo *) viene usato per accettare ogni valore non

corrispondente con la lista dei valori. case $var inval1)

statements;;val2)

statements;;*)

statements;;esac

Page 32: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.32

Costrutti di iterazione Il ciclo for viene usato quando si vuole ripetere un blocco di

comandi in corrispondenza di valori tratti da un elenco. for var in listdo istruzionidone

Le istruzioni vengono eseguite assegnando a var ciascun valore in list. #!/bin/bashlet sum=0for num in 1 2 3 4 5do let sum=$sum+$numdoneecho $sum

Page 33: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.33

Costrutti di iterazione: <list> #!/bin/bash

for x in paper pencil pen; do echo “The value of variable x is: $x” sleep 1done

# The value of variable x is paper# The value of variable x is pencil# The value of variable x is pen

#!/bin/bashfor x in “paper A4” “pencil STADTLER” “pen BIC”; do echo “The value of variable x is: $x” sleep 1done

# The value of variable x is paper A4# The value of variable x is pencil STADTLER# The value of variable x is pen BIC

Page 34: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.34

Costrutti di iterazione: <list>

#!/bin/bashlista=“antonio michelepaololuca”

for x in $listado echo “The value of variable x is: $x” sleep 1done

# The value of variable x is antonio# The value of variable x is michele# The value of variable x is paolo# The value of variable x is luca

Page 35: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.35

Costrutti di iterazione: <list>

#!/bin/bash

for x in *do ls -l “$x” sleep 1done

# Lists all files in current directory

#!/bin/bash

for x in /bindo ls -l “$x”done

# Lists all files in /bin

Page 36: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.36

Costrutti di iterazione: <list>

#!/bin/bash read –p “Insert the name of a directory” directory

echo "symbolic links in directory \“ $directory \“ " for file in $( find $directory -type l ) # -type l =

symbolic links do

echo "$file" done | sort # Otherwise file list is unsorted

Page 37: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.37

Costrutti di iterazione: <list>

Se la parte list viene omessa, a var viene assegnato ciascun parametro passato allo script ( $1, $2, $3,…).

Page 38: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.38

Costrutti di iterazione: <list>

Se la parte list viene omessa, a var viene assegnato ciascun parametro passato allo script ( $1, $2, $3,…).

Page 39: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.39

Operazioni sulle variabili

……let “index += 5” #incrementa la variabile

#index di 5

……

+= #incrementa la variabile-= #decrementa la variabile*= #moltiplica la variabile/= #divide la variabile

Page 40: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.40

Arrays Nella shell bash, possiamo usare gli arrays. Il modo

più semplice per crearne uno è usare uno dei due metodi seguenti: pet[0]=dogpet[1]=catpet[2]=fishpet[4]=apple

pet=( dog cat fish apple ) Si possono inserire fino a 1024 elementi. Per

estrarre un valore, digitare ${arrayname[i]}. $ echo ${pet[0]} dog

$ echo ${pet[2]} fish

Page 41: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.41

Arrays

Per estrarre tutti gli elementi, usare un asterisco come segue: echo ${arraynames[*]}

Per vedere quanti elementi ci sono nell’array:echo ${#arraynames[*]}

Si possono utilizzare gli arrays nei cicli per realizzare la lista di un ciclo for: for x in ${arrayname[*]}doecho $xdone

Page 42: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.42

Un “for” alternativo Una forma alternativa per la struttura for è

for (( EXPR1 ; EXPR2 ; EXPR3 ))do

istruzionidone

Per prima cosa, viene valutata l’espressione aritmetica EXPR1. Quindi EXPR2 viene valutata ripetutamente fino a che non assume risulta falsa. Ogni volta che EXPR2 è vera, le istruzioni vengono eseguite e, in coda, viene eseguita EXPR3.

Page 43: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.43

Debugging Bash fornisce due opzioni che danno informazioni utili per il

debugging:-v : visualizza ciascuna linea dello script così come era stata digitata

prima dell’esecuzione;

-x : simile a sopra, ma se c’è un ciclo mostra tutti le iterazioni.

Utilizzo: #!/bin/bash –v, o #!/bin/bash –x $ cat for3.sh

#!/bin/bash –x

echo –n “Enter a number: ”; read x

let sum=0

for (( i=1 ; $i<$x ; i=$i+1 )) ; do

let “sum = $sum + $i”

done

echo “the sum of the first $x numbers is: $sum”

Page 44: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.44

Debugging$ ./for3.sh+ echo –n ‘Enter a number: ’Enter a number: + read x3+ let sum=0+ (( i=0 ))+ (( 0<=3 ))+ let ‘sum = 0 + 0’+ (( i=0+1 ))+ (( 1<=3 ))+ let ‘sum = 0 + 1’+ (( i=1+1 ))+ (( 2<=3 ))+ let ‘sum = 1 + 2’+ (( i=2+1 ))+ (( 3<=3 ))+ let ‘sum = 3 + 3’+ (( i=3+1 ))+ (( 4<=3 ))+ echo ‘the sum of the first 3 numbers is: 6’the sum of the first 3 numbers is: 6

Page 45: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.45

Dov’è l’errore?

Uno script da correggere#!/bin/bash # ex74.sh a=37 if [$a -gt 27 ] then echo $a fi

Output dello script: ./ex74.sh: [37: command not found

Page 46: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.46

Dov’è l’errore?

Uno script da correggere#!/bin/bash -x# ex74.sh a=37 if [$a -gt 27 ] then echo $a fi exit 0

Output dello script: +a=37+’[37’ -gt 37 ‘]’+ ./ex74.sh: [37: command not found….

Page 47: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.47

Il costrutto While La struttura while è una struttura di ciclo che viene usata

per eseguire un insieme di comandi finchè una certa condizione specificata è vera. Il ciclo termina non appena la condizione diventa falsa. Se la condizione non diventa mai falsa, il ciclo non termina e si entra in loop.

while espressionedo

istruzionidone

Page 48: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.48

Il costrutto continue Il comando continue genera un salto all’iterazione

successiva del ciclo, dimenticando tutti i restanti comandi in quella particolare iterazione.

#!/bin/bash LIMIT=19

echo echo “Printing Numbers 1 through 20 (but not 3 and 11)”

a=0 while [ $a -le “$LIMIT” ]; do a=$(($a+1)) if [ “$a” -eq 3 ] || [ “$a” -eq 11 ] then

continue fi echo -n “$a ” done

Page 49: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.49

Il costrutto break Il comando break termina il ciclo (ed esce da esso).

#!/bin/bash

LIMIT=19

echo “Printing Numbers 1 through 20, but something happens after 2 … ”

a=0

while [ $a -le “$LIMIT” ]; do

a=$(($a+1))

if [ “$a” -gt 2 ]

then

break

fi

echo -n “$a ”

done

echo; echo; echo

Page 50: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.50

Il costrutto untilLa struttura until è molto simile alla struttura

while. La struttura until mantiene il ciclo finchè la condizione è falsa. Quindi, sostanzialmente, il significato è “finchè la condizione è falsa, fai questo”.

until [espressione]do

istruzionidone

Page 51: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.51

Manipolare le stringhe Bash supporta un numero impressionante di operazioni per

manipolare stringhe. Sfortunatamente, questi strumenti non soddisfano una delle primitive esigenze di Linux, cioè quella dell’economicità dei comandi. ${#string} rende la lunghezza della stringa. ${string:position} estrae da $string la sottostringa che

inizia dalla posizione $position. ${string:position:length} estrae $length caratteri della

sottostringa di $string che inizia dalla posizione $position.

Esempio: $ st=0123456789

$ echo ${#st}10 $ echo ${st:6} 6789 $ echo ${st:6:2} 67

Page 52: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.52

Sostituzione dei parametri Manipolare e/o espandere variabili:

${parameter-default}, se “parameter” non è istanziato, usa “default”.

$ echo ${username-”lferrari”}

lferrari

$ username=luca

$ echo ${username-”lferrari”}

luca

${parameter=default}, come sopra. ${parameter+value}, se “parameter” è istanziato,

usa value, altrimenti usa la stringa vuota.$ echo ${username+andrea} andrea$ echo ${pippo+andrea} # null string

Page 53: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.53

Sostituzione dei parametri ${parameter?msg}, Se “parameter” è istanziato, lo

usa, altrimenti stampa msg.$ value=${total?’total is not set’}

-bash: total: total is not set

$ total=10

$ value=${total?’total is not set’}

$ echo $value

10

Esempio: #!/bin/bash

OUTFILE=symlinks.list

directory=${1-`pwd`}

for file in “$( find $directory -type l )”

do

echo “$file”

done | sort >> “$HOME/$OUTFILE”

Page 54: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.54

Operazioni avanzate sulle stringhe

${string#substring}, elimina la più corta occorrenza corrispondente a substring dall’inizio di string.

pippo=abbcaabccbcabcdbcdabaecho ${pippo#a*c}

# aabccbcabcdbcdabaecho ${pippo##a*c} # strips the longest match

# daba

Page 55: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.55

Operazioni avanzate sulle stringhe

${string/substring/replacement}, elimina la prima occorrenza corrispondente a substring in string, rimpiazzandola con replacement.

pippo=abbcaabccbcabcdbcdabab echo ${pippo/ca/11}

# abb11abccbcabcdbcdababecho ${pippo//ca/11}

# abb11abccb11bcdbcdabab # replaces all matchesecho ${pippo/[ab]?c/000}

# a000aabccbcabcdbcdababecho ${pippo/c*a/\!}

# abb!becho ${pippo//b?/00}

# a00caa00c00a00d00da00b

Page 56: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.56

Funzioni Le funzioni rendono gli scripts più facili da mantenere.

Sostanzialmente, permettono di suddividere il programma in pezzetti più piccoli. Una funzione esegue un’azione definita dall’utente, e può rendere un valore se l’utente lo desidera. #!/bin/bashhello(){echo “You are in function hello()”} echo “Calling function hello()…”helloecho “You are now out of function hello()”

Sopra, abbiamo richiamato la funzione hello() col suo nome usando la linea: hello. Quando questa linea viene eseguita, bash cerca nello script la linea hello(). La trova, e ne esegue i contenuti.

Page 57: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.57

Funzioni#!/bin/bashfunction check() {if [ -e "/home/$1" ]then return 0else return 1fi}

echo “Enter the name of the file: ” ; read xif check $xthen echo “$x exists !” else echo “$x does not exist !” fi.

Page 58: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.58

Massimo comun divisore

#!/bin/bash # gcd.sh: massimo comun divisore # Si usa l’algoritmo di Euclide# Il “massimo comun divisore" (gcd) di due interi è il più

grande intero# che divide entrambi, senza che ci sia del resto. # L’algoritmo di Euclide utilizza divisioni successive. # Ad ogni passo, dividend <--- divisor, divisor <--- remainder # finchè remainder = 0. Nell’ultimo passo, si ha gcd =

dividend.

ARGS=2 E_BADARGS=65 if [ $# -ne "$ARGS" ] then

echo "Usage: `basename $0` first-number second-number" exit $E_BADARGS

fi

Page 59: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.59

Massimo comun divisore

gcd () { dividend=$1 divisor=$2 remainder=1 until [ "$remainder" -eq 0 ] do let "remainder = $dividend %

$divisor" dividend=$divisor

divisor=$remainder done } # Last $dividend is the gcd. gcd $1 $2 echo; echo "GCD of $1 and $2 = $dividend“

Page 60: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.60

Script 1: estrarre una carta a caso da un mazzo

#!/bin/bash

Suites=“Clubs Diamonds Hearts Spades”Denominations=“2 3 4 5 6 7 8 9 10 Jack Queen King Ace”

# Read into array variable. suite=($Suites) denomination=($Denominations)

# Count how many elements. num_suites=${#suite[*]}num_denominations=${#denomination[*]}

# Extractecho -n "${denomination[$((RANDOM%num_denominations))]}

of " echo ${suite[$((RANDOM%num_suites))]}

Page 61: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.61

Script 2: cambiare i nomi di tutti i file mettendoli in lettere minuscole

#!/bin/bash for filename in * # Traverse all files in directory. do fname=`basename $filename`

# Change name to lowercase. n=`echo $fname | tr A-Z a-z` if [ “$fname” != “$n” ] # Rename only files not already lowercase.

then mv $fname $n fi done

Page 62: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.62

Script 3: Confrontare due files con uno script#!/bin/bash

ARGS=2 # Two args to script expected. if [ $# -ne “$ARGS” ]; then echo “Usage: `basename $0` file1 file2” ; exit 1fi if [ ! -r "$1“ ] || [ ! -r "$2" ] ; then echo “Both files must exist and be readable.” ; exit 2

fi cmp $1 $2 &> /dev/null # /dev/null buries the output of the “cmp” command. # Also works with 'diff', i.e., diff $1 $2 &> /dev/null

if [ $? -eq 0 ] # Test exit status of “cmp” command.then echo “File \“$1\” is identical to file \“$2\”.” else echo “File \“$1\“ differs from file \“$2\”.” fi

Page 63: 1.1 La shell di Linux Linux ha una varietà di shell differenti: Bourne shell (sh), C shell (csh), Korn shell (ksh), TC shell (tcsh), Bourne Again shell

1.63

Esercizio#!/bin/bash MAX=10000 for((nr=1; nr<$MAX; nr++)) do

let "t1 = nr % 5" if [ "$t1" -ne 3 ] then continue fi

let "t2 = nr % 7" if [ "$t2" -ne 4 ]then continue fi

let "t3 = nr % 9" if [ "$t3" -ne 5 ] then continue fi

break # What happens when you comment out this line? Why?

done

echo "Number = $nr" exit 0