Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D Le Miniguide all'orientamento Gli eBook di Federica La Corte in Rete
 
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Clemente Galdi » 2.Principi di programmazione Shell


Unix Shell

La Shell di Unix è un interprete delle “linee di comando” attraverso le quali l’utente utilizza le risorse del sistema.
Permette la gestione di variabili e dispone di costrutti per il controllo del flusso delle operazioni.

Può essere utilizzata in modalità:

  • Interattiva: Accettando input da tastiera;
  • Non interattiva: Redirigendo l’I/O su file.

Viene generalmente eseguita in modalità interattiva, all’atto del login, restando attiva per tutta la durata della sessione di lavoro, effettuando le seguenti operazioni:

  • Gestione del main command loop;
  • Analisi sintattica dei comandi;
  • Esecuzione di comandi (built-in, file eseguibili) e programmi in linguaggio di shell (script);
  • Gestione dello standard I/O e dello standard error;
  • Gestione dei processi da terminale.

Le shell di Unix

I sistemi Unix offrono diverse shell:

  • sh: Bourne shell. La shell presente sui primi sistemi Unix. Ancora presente su tutti i sistemi Unix per questioni di compatibilità.
  • bash: Shell di default per gli utenti Linux. Estende la sh ed, in genere, gli script sh funzionano in bash. NON è vero il viceversa.
    • È conforme alla sezione IEEE POSIX Shell and Tools dello standard IEEE POSIX 1003.1, anche noto come “Standard POSIX”
    • È la shell di riferimento in questo corso.
  • csh: La sintassi ricorda quella del linguaggio C. Richiesta, in alcuni casi, espressamente da programmatori.
  • tcsh: “Turbo” csh. Estende la csh rendendola piu’ “user-friendly”.

Shell diverse hanno sintassi leggermente diverse.
In molti sistemi Unix il file /etc/shells contiene l’elenco delle shell installate dall’amministratore e disponibili a tutti gli utenti.

  • Ogni utente può installare nella propria home directory una shell ma questa non sarà’ automaticamente disponibile a tutti gli utenti.

Shell Interattiva

La shell interpreta la prima “parola” come:

  • Il nome di un file eseguibile: Un file presente sul file system in formato ELF (Executableand Linking Format).
    • Esempio: “ls” corrisponde al file “/bin/ls
    • Il formato ELF “equivale” al formato “exe” in windows
  • Il nome di un comando “built-in”: Comandi implementati “all’interno” della shell
    • Alcune operazioni non possono essere eseguite all’esterno della shell perchè modificano la stato della shell
    • Esempio: “cd” è un comando built-in, i.e., NON corrisponde a nessun file, e modifica una variabile interna alla shell.
  • Il nome di uno “script shell”: Una sequenza di comandi built-in, script shell e/o file eseguibili. Visto che esistono shell diverse, gli script shell devono essere scritti per una shell specifica. È possibile eseguire uno script come segue:
    • nomeshell nomescript (ad es., bash mioscript). Questa modalità è sconsigliata perché assume la conoscenza della shell per cui lo script è stato scritto.
    • nomescript (ad es., mioscript). Modalità’ consigliata. Affinchè uno script sia eseguibile in questo modo:
      • È opportuno indicare, utilizzando sulla prima riga la direttiva #!, all’interno dello script quale sia la shell per cui lo script è stato scritto. Ad es., nel caso della bash, la prima riga sarà:
        • #!/bin/bash
      • È necessario settare i permessi di esecuzione sul file.

Il Profilo utente

Quando invocata, ogni shell esegue una serie di script di personalizzazione definiti dall’amministratore e/o dall’utente.
Le shell si dividono in:

  • Login shell: shell eseguita dal sistema operativo dopo una fase di autenticazione, detta login.
  • Non-login shell: shell eseguita dall’utente, e.g., selezionando l’applicazione da un menu.

Ogni shell definisce i propri script di personalizzazione.

  • Tutte le shell eseguono:
    • /etc/profile: Profilo generico comune a tutti;
    • ~/.profile: Proprio profilo utente.
  • Bash specific
    • /etc/bashrc: Profilo generico comune a tutti gli utenti bash
    • ~/.bash_profile, ~/.bash_login: Profilo definito dall’utente
    • ~/.bashrc: Proprio profilo utente. Usato per “non-login shel”

NON utilizzare costrutti bash in /etc/profile o ~/.profile.

Variabili d’ambiente

Il comportamento di tutte le shell è definito attraverso alcune variabili d’ambiente.
Alcuni esempi:

  • HOME: Identifica la “home directory” dell’utente letta dal file /etc/passwd;
  • PATH: La lista delle directory in cui la shell ricerca I file eseguibili e gli shell script;
  • PS1: stringa del prompt, il default e’ “$” per l’utente e “#” per il super-user;
  • PS2: prompt per comandi “multi-riga”;
  • PWD: Directory corrente.

È possibile utilizzare il comado printenv per visualizzare le variabili d’ambiente.

Esecuzione di comandi

L’esecuzione di un comando avviene creando un nuovo processo, detto processo figlio, che esegue il programma richiesto.
La sintassi del comandi Unix è:

comando [argomento ...]

Gli argomenti possono essere:

  • opzioni o flag (-)
  • parametri separati da almeno un separatore

La prima “parola” identifica il comando:

  • Funzione/Script shell, comando built-in o eseguibile;
  • Gli eseguibili e gli script vengono ricercati nella sequenza di directory indicate dalla variabile PATH, esattamente nell’ordine in cui queste sono presentate;
  • La bash usa una hash table contenente comandi e script che consente di evitare la ricerca nel file system.

Processi in foreground e backgroud

La richiesta di esecuzione di un comando implica la creazione di un nuovo processo.
I processi eseguiti all’interno di una shell possono essere:

  • In foreground: sottraggono alla shell il controllo del terminale durante la loro esecuzione;
  • In background, il controllo del terminale rimane alla shell: il prompt appare immediatamente dopo che il processo è stato avviato;
  • Per default, i processi vengono lanciati in foreground.

Per segnalare alla shell che si vuole lanciare il comando (o lo script) in background, è necessario farne seguire il nome dal carattere & :

comando [argomento..] &

Redirezione di standard I/O

comando [argomento..] > nomefile
L’output del comando viene scritto in nomefile. Se file non esiste viene creato, altrimenti viene sovrascritto.
comando [argomento..] >> nomefile
L’output del comando viene scritto in nomefile. Se file non esiste viene creato, altrimenti l’output viene accodato.
comando [argomento..] < nomefile
Il contenuto di nomefile viene passato in input al comando.
comando [argomento..] 2> nomefile
Lo standard error del comando viene scritto in nomefile. Se il file non esiste viene creato, altrimenti viene sovrascritto.
comando [argomento..] 2>> nomefile
Lo standard error del comando viene scritto in nomefile. Se file non esiste viene creato, altrimenti l’output viene accodato.
comando [argomento..] > /dev/null 2>&1
/dev/null è un file speciale. Qualunque informazione scritta su questo file viene cestinata.
L’output che il comando invia sullo standard output viene cestinato. L’output inviata sullo standard errorviene rediretto sullo standard output (e quindi anch’esso su /dev/null).
Legenda:
1=standard output
2=standard error

Esecuzione di comandi

Per eseguire un comando, la shell:

  1. Legge una stringa da terminale o da file;
  2. Suddivide l’input in token separati da metacaratteri
    • I metacaratteri in bash sono | & ; ( ) < > spazio tab;
  3. Effettua il parsingdei token identificando I comandi “semplici” e le composizioni di comandi
    • Ad es., è possibile richiedere l’esecuzione concorrente di più comandi
  4. Esegue le shell expansion, sostituiendo, ove richiesto, una lista di stringhe ad un token. Ad es.:
    • Tilde expansion. Al token “~/” viene sostituita la stringa che identifica la home directory dell’utente
    • Variable expansion. Al token “$nomevar” viene sostituito il valore della variabile nomevar;
  5. Esegue la redirezione dell’I/O. Consente di dirottare la lettura dell’input (scrittura dell’output) dalla tastiera (monitor) ad un file;
  6. Esegue I comandi richiesti;
  7. Eventualmente, attende la terminazione dei comandi.

Caratteri speciali

I caratteri speciali sono caratteri o gruppi di caratteri che vengono utilizzati per fornire indicazioni alla shell. Di seguito riportiamo le direttive codificate da alcuni caratteri speciali:

  • | (pipe): Indica alla shell di eseguire concorrentemente il comando a sinistra ed a destra della pipe. L’output del comando a sinistra della pipe diventa l’input del comando a destra della stessa. Ad es., ls -l | sort
  • && (AND logico): Il comando a destra dell’AND viene eseguito se e solo se il comando a sinistra dell’AND termina con un valore di uscita zero.
  • || (OR logico): Il comando a destra dell’OR viene eseguito se e solo se il comando a sinistra dell’OR ritorna un valore NON-zero.
  • < (redirezione dello standard input): Indica alla shell di leggere l’input da un file invece che da tastiera
  • > (redirezione dello standard output): Indica alla shell di scrivere l’output su un file invece che su monitor
  • * corrisponde ad una stringa qualunque (anche vuota)
  • ? corrisponde ad un carattere singolo qualsiasi
  • [...] corrisponde ad uno dei caratteri racchiusi

Un elenco esteso dei caratteri speciali è disponibile al seguente indirizzo: http://www.pluto.it/files/ildp/guide/abs/special-chars.html

Definizione delle variabili

Tutte le shell consentono la definizione di variabili, i.e., di contenitori di informazioni. La shell stessa utilizza variabili, visibili all’utente, per mantenere lo stato dell’interazione con l’utente (e.g., la directory corrente) o le preferenza dell’utente (e.g., il prompt utente). Le variabili possono essere:

  • Globali: Visibili a tutte le shell dello stesso utente
    • Anche dette variabili d’ambiente
    • Visualizzabili utilizzando i comandi env e/o printenv
    • Le variabili d’ambiente vengono ereditate da tutti i processi generati dalla shell corrente
  • Locali: Visibili solo alla shell corrente
    • Le variabili definite dall’utente sono, per default, locali
    • Visualizzabili attraverso il comando set
    • NON vengono ereditate dai processi creati dalla shell

Per rendere una variabile locale visibile ai (soli) processi generati dalla shell corrente è possibile utilizzare il comando export.
La modifica ad una variabile globale od esportata:

  • Ha effetto sulla shell che la esegue e su tutti I figli generati successivamente alla modifica;
  • NON ha effetto sul processo padre della shell (I.e., la “shell che ha generato la shell corrente”) o sui figli generati prima della esecuzione della modifica.

Definizione delle variabili (segue)

Regole di naming. I nomi di variabili:

  • Sono case-sensitive.
  • Possono essere composti da lettere (maiuscole e minuscole), digit ed underscore.
  • Non possono iniziare per un digit.
  • Per convenzione, I nomi delle variabili d’ambiente sono composto da soli caratteri maiuscoli.

Esempi:

  • Le variabili NOME, NoMe, nome e nomE sono diverse.
  • Nomi ammissibili: Var1, V1D2, Nome_Cognome, _Nome, _1_2_3
  • Nomi errati: 1Var, Nome-Cognome, Val$ore, Tre*due

Definizione delle variabili (segue)

Per definire una variabile (locale) è possibile utilizzare la seguente sintassi:

  • Nome_variabile=valore
    • Non far precedere o seguire l’operatore “=” da spazi
    • È consigliabile includere il valore in una coppia di apici doppi (” “), ad es.
      • Messaggio=”Corso”
    • L’inclusione tra apici è obbligatoria qualora il valore includa spazi
      • Nome=”Laboratorio di Sistemi Operativi”
  • Per esportare una variabile è possibile utilizzare una delle seguente sintassi:
    • export nomevar
    • export nomevar=”valore”

Nomi riservati

Per referenziare il valore di una variabile è necessario utilizzare il carattere special $ seguito dal nome della variabile:

  • Es. Variabile=”valore”; echo $Variabile

È possibile passare parametri ad uno script.
Gli argomenti di uno script sono posizionali e vengono indicati mediante un intero (0, 1, 2, 3…):

  • $0 rappresenta il nome del file contenente dello script;
  • I parametri $1, $2... rappresentano, nell’ordine, gli argomenti passati in input allo script;
  • Per indicare i parametri successivi al nono è necessario utilizzare la notazione ${10}, ${11},…
  • $# rappresenta il numero di argomenti passati in input allo script;
  • $@ rappresenta l’insieme di tutti gli argomenti dati in input allo script. Se lo script riceve meno di nove argomenti, a quelli mancanti corrispondono stringhe vuote.

Il comando shift esegue una rotazione a sinistra dei parametri.
Rende possibile processare in modo iterativo i parametri uno per volta.

Esempio

Esempio di modifica della variabile $PATH: Mostra codice

La variabile PATH contiene la sequenza delle directory, divise da ":", in cui la shell ricerca i file eseguibili.
Nell'esempio, l'utente richiede l'esecuzione del comando ps. La shell ricerca un file eseguibile nella directory /usr/bin. Se non esiste nessun file con quel nome in questa directory, ricerca un file "ps" nella directory /home/lso. Se non lo trova cerca il file nella directory corrente (indicata dalla presenza del ".").

Chiaramente l'utente può modificare la variabile $PATH. Essendo questa, però, una variabile d'ambiente. La sua modifica implica una modifica del comportamento della shell.
Nell'esempio, l'aggiunta della directory "/bin" alla variabile PATH consente alla shell di eseguire il comando ps.

Esempio (Segue)

Concatenazione di variabili shell: Mostra codice

Il secondo esempio concentra l'attenzione sulla concatenazione di valori di variabili.
La concatenazione avviene giustapponendo, senza spazi, i valori delle variabili e/o delle costanti.
Nel caso di ambiguità, i caratteri speciali { e } consentono di identificare l'inizio e la fine del nome di una variabile.
L'assegnazione ad una variabile di una stringa contenente spazi richiede la protezione del metacarattere spazio attraverso il quoting. L'utilizzo degli apici doppi o singoli dipende dall'utilizzo della stringa.

Esempio (segue)

Esempio di utilizzo dei parametri: Mostra codice
Lo script esegue una visualizzazione dei parametri passati allo script.
La prima riga visualizza il nome del file contenente lo script, utilizzando il parametro $0.
Vengono successivamente visualizzati:

  • i primi due parametri, separatamente, utilizzando le variabili $1 e $2,
  • il numero di argomenti passati allo script, tramite $#
  • una stringa contenete tutti I parametri passati allo script, tramite $@.

A questo punto, il comando shift esegue una rotazione a sinistra dei paramtri. L'effetto di shift è l'eliminazione del primo parametro, ed una ridefinizione del numero di parametri passati, della posizione dei parametri e della stringa contenete tutti i parametri. Da questo momento in poi, il primo parametro non è più recuperabile.

Difatti, nell'esempio di esecuzione: Mostra codice

- la variabile $# assume il valore tre prima dello shift e due dopo lo shift
- la variabile $2 assume il valore "due" prima dello shift e "tre" dopo lo shift
- la variabile $@ assume il valore "uno due tre" prima dello shift e "due tre" dopo lo shift.
Si noti che shift non ha effetto sulla variabile $0.

Array di variabili

In bash è possibile definire array di variabili.
Non è necessario definire la dimensione dell’array ne la shell definisce una dimensione massima.
Il primo elemento dell’array ha indice 0.
Per definire un array è possibile utilizzare una delle seguenti sintassi:
Nomearray[indice]=valore, dove “indice” viene trattata come una espressione aritmetica il cui valore deve essere non negativo.
declare -a Nomearray
Nomerray=(valore1 valore2 … valoren)

Per aggiungere/modificare un elemento dell’array, è possibile utilizzare la scrittura Nomearray[indice]=valore.
Per referenziare un elemento in un array è necessario utilizzare la seguente sintassi:

  • ${Nomearray[indice]} accede all’elemento indicato nell’array
  • ${Nomearray[*]} elenca tutti gli elementi dell’array
  • Attenzione: $Nomearray è un riferimento al primo elemento dell’array

Per cancellare un elemento dall’array è possibile utilizzare la seguente:

  • Cancella l’elemento indice: unset nomearray[indice]
  • Cancella tutto gli elementi dell’array: unset nomearray[*]

Esempio

La dichiarazione “esplicita” dell’array attraverso declare è, in realtà, inutile vista la dichiarazione “implicita” attraverso l’inizializzazione dell’array. È, comunque, buona norma, ove possibile, cercare di tipizzare esplicitamente le variabili utilizzate.
La scrittura $array[*] viene suddivisa dalla shell come:

  • $array“: In bash il nome dell’array è implicitamente un riferimento alla prima locazione dell’array. Quindi la scrittura $array viene inteepretata come Sostituzione del primo elemento dell’array.
  • [*]“: Stringa costante.

È possibile inserire un elemento in qualsiasi posizione dell’array. Difatti, nell’esempio che segue: Mostra codice, viene inserito un elemento nella posizione 10 dell'array, sebbene le precedenti siano vuote.

La cancellazione degli elementi in un array può essere puntuale, indicando l'indice dell'elemento da cancellare, o globale, indicando "*"> in quest'ultimo caso, tutti gli elementi dell'array saranno cancellati.

Output dello script: Mostra codice

Quoting

La shell interpreta i caratteri speciali (e le keywords). In taluni casi, però, si rende necessario evitare l’interpretazione o, come vedremo, l’espansione.

  • Ad esempio: Come è possibile visualizzare il messaggio “Costa $3“. La shell sostituirebbe “$3” con il valore del terzo parametro passato allo script.

Esistono diverse tecniche che consentono di proteggere (evitare l’interpretazione di) I caratteri speciali:

  • Quoting attraverso apici doppi: Racchiudere una stringa/variabile all’interno di “…”
    • Protegge i caratteri speciali contenuti nella stringa.
    • Non protegge i caratteri $, ` e \
    • È necessario utilizzare questa tecnica per preservare gli spazi ed i caratteri di tabulazione, e.g., per la visualizzazione tramite echo o per evitare che una stringa che contiene spazi venga suddivisa in più stringhe.
  • Quoting attraverso apice singolo: Racchiudere una stringa/variabie all’interno di ‘…’
    • Protegge tutti i caratteri speciali (ecceto l’apice singolo)
  • Escaping o quoting di un singolo carattere: Inserire un carattere backslash “\” prima del carattere speciale
    • Indica alla shell di non interpretare il carattere protetto.
    • Con alcuni comandi (echo e sed), il carattere speciale backslash ha il ruolo di “convertire” caratteri standard in caratteri speciali, e.g., per echo, la coppia di caratteri \n viene interpretata come newline.

Esempio

Il seguente script: Mostra codice, mostra alcuni esempi di quoting ed escaping. Vengono definite due variabili, a e b, che differiscono semplicemente per il numero di spazi tra le parole "uno" e "due". Per comodità di lettura, l'output include un indice di riga.
Sebbene a e b siano diverse, gli output con indice 1 e 2 sono identici a causa della mancata protezione dei metacaratteri spazio. Il comando echo, difatti, sopprime le occorrenze multiple di questi metacaratteri in b.
Se proteggiamo gli spazi in a e b tramite quoting con apici doppi, gli output che otteniemo (3 e 4) riproducono fedelmente le variabili a e b. Si noti che le seguenti scritture sono equivalenti: echo "3->$a" ed echo "3->""$a"
La presenza di un backslash in 5 serve a proteggere il carattere speciale $. In questo caso, il \ evita che la shell interpreti $ come "sostituzione di variabile".
Si noti che, in 6, il primo backslash serve a proteggere il secondo backslash. La shell, quindi intepreta "\\" come "visualiza il carattere \" ed i successivi "$b" come "sostituisci il valore della variabile b".
Infine, l'utilizzo dell'apice singolo, in 7,8 e 9, protegge tutti I caratteri speciali tranne l'apice stesso.
La riga 10 viene suddivisa dalla shell come segue:
'10->\'. Visualizza la stringa constante 10->\
\': Visualizza il carattere ' (protetto dal carattere di escape)
'\$a': Visualizza la stringa $a (protetta dal quoting)

Output dello script: Mostra codice

Exit

Il comando exit termina uno script ed, opzionalmente, ritorna alla shell un valore.
Per convenzione, uno script ritorna zero in caso di successo. Altrimenti, il valore di ritorno può essere utilizzato per dare indicazioni sull’errore che si è verificato.

Se lo script termina con un exit senza parametri o senza exit, il valore di ritorno dello script è pari al valore di ritorno dell’ultimo comando eseguito all’interno dello script.
Lo script può ritornare un intero nel range 0, 255 utilizzando la scrittura exit n.

Shell Expansion

Dopo la suddivisione dell’input in token, la shell “espande” se necessario i singoli token.
Ovviamente, l’espansione avviene se e solo se i caratteri speciali NON sono protetti.
Espansione delle parentesi: La stringa Prefisso{s1,s2,s3…}Suffisso viene espansa dalla shell generando tutte le stringhe del tipo PrefissosiSuffisso.
Il Suffisso è opzionale;
È possibile annidare le brace expansion.
Espansione della Tilde: Il carattere speciale ~ viene utilizzato dalla shell per indicare la home directory di un utente. In particolare:

  • ~/ viene sostituita dal contenuto della variabile HOME dell’utente che esegue la shell
  • ~nomeutente/ viene sostituita dalla home directory dell’utente la cui username è “nomeutente”

Shell Expansion (segue)

Espansione delle variabili: Abbiamo già menzionato l’espansione effettuata attraverso il carattere speciale $, i.e., la shell interpreta $nomevar o ${nomevar} sostituendo il valore della variabile nomevar.
Sostituzione dei comandi: La shell consente la possibilità di ottenere l’output di un comando, in modo da poterlo processare successivamente. Esistono due possibili sintassi:

  • $(com) oppure `com`: La shell esegue il comando com in una subshell. Viene quindi creata una variabile contenente l’output del comando.
    • Attenzione: Gli apici di comando ` sono diversi dagli apici singoli ‘
  • Esempio: a=$(ls -l); echo “$a”

Esempio

Il seguente script: Mostra codice, mostra un esempio di espansione annidata di parentesi. Sono presenti un prefisso "P" ed un suffisso "S".

Le variabili a e b corrispondono alle home directory dell'utente corrente (galdi) e dell'utente "corsi" rispettivamente. La shell sostituisce la scrittura "~/" con la stringa "/home/galdi" e la scrittura "~corsi" con "/home/corsi"/

L'esempio illustra la sostituzione di comando. Nello specifico, la shell.

  1. Sostituisce la variabile $a con il suo contenuto (/home/galdi), a sua volta ottenuto attraverso la sostituzione della ~.
  2. Esegue il comando composto ls /home/galdi | wc -l. Questo comando consiste nell'esecuzione concorrente, definita dall'operatore |, di ls e wc. Inoltre, l'output di ls /home/galdi diventa input di wc -l
  3. Sostituisce alla stringa `ls $a|wc -l` l'output del comando composto
  4. Visualizza la stringa risultante dalla concatenazione delle stringhe "Il numero di file in", "/home/galdi", "e", "18"

Si noti che l'output la sostituzione di comando può essere assegnata ad una variabile per essere processata successivamente: Mostra codice

Shell Expansion

Espansione aritmetica: Consente la valutazione di espressioni aritmetiche.

  • La sintassi è: $((Espressione))
  • Possibile utilizzare il comando built-in let: let variabile=espressione, e.g. let a=$a+1
  • Le espressioni aritmetiche possono essere annidate
  • È possibile utilizzare all’interno delle espressioni variabili e costanti. Le variabili vengono opportunamente espanse dalla shell prima della valutazione dell’espressione.
  • La valutazione viene effettuata su interi senza nessun controllo su eventuali overflow.
  • Gli operatori sono simili a quelli utilizzati nel linguaggio C, e.g., pre/post-incremento, +, -, *, /, **, operatori logici ||, &&, !, operatori logici bitwise &, |, ~, operatori di shift <<, >>, operatori di confronto <=, >=, <, > etc.

Shell Expansion (segue)

Suddivisione dell’output in parole: Se il risultato delle espansioni non viene assegnato ad una variabile o processato esplicitamente, la shell interpreta l’output dell’espansione come un comando od una sequenza di comandi da eseguire.

  • La shell esegue una scansione del risultato, suddividendolo in token. Il separatore utilizzato durante questa scansione è contenuto nella variabile IFS. Se questa variabile non è settata, i separatori di default sono spazio, tab e newline.
  • È possibile evitare la scansione, proteggendo l’output dell’espansione includendolo tra apici doppi.

Espansione dei nomi dei file: Successivamente alla suddivisione in parole, la shell ricerca all’interno di ogni parola I caratteri speciali *, ?, [, ., ..

  • Per I primi esegue l’espansione opportuna,
  • Per I caratteri . e .. verifica la posizione all’interno della stringa e ricalcola I percorsi opportunamente.

Esempio

Il seguente script: Mostra codice, illustra alcuni esempi di espansione aritmetica.
Innanzitutto si ricorda che le operazioni vengono effettuate su interi ed hanno risultato intero. Quindi, il rapporto tra 5 e 3 e' pari ad 1.
La scrittura $((a/b)) implica il calcolo del rapporto tra il contenuto delle variabili a e b. La presenza del $ indica alla shell la necessità di effettuare la sostituzione aritmetica, I.e., la stringa "((a/b))" deve essere sostituita dal valore del rapporto a/b. Questo valore è assegnato alla variabile r.
Si noti che le due scritture $((a/b)) e $(($a/$b)) sono entrambe corrette. L'utilizzo della sostituzione di variabile all'interno delle espressioni è opzionale.

ATTENZIONE: È sbagliato utilizzare forme del tipo (($a++)). Questa scrittura equivarrebbe a $a=$a+1. Ma $a è il valore della variabile a, NON la variabile a, e quindi NON è possibile assegnare a $a alcunché.
Il comando built-in let può essere utilizzato per eseguire operazioni aritmetiche.
È infine necessario notare che la scrittura $((espressione)) viene interpretata dalla shell in due fasi. In una prima fase, la shell valuta l'espressione in ((espressione)). Nella seconda fase, la presenza del $ indica alla shell di "ritornare" il valore calcolato. In realtà la prima fase è indipendente dalla seconda. In particolare, è possibile utilizzare la scrittura ((espressione)), senza il "$". Questa scrittura indica alla shell semplicemente di valutare l'espressione, modificando, se richiesto, le variabili in essa contenute. Nell'esempio, ((a++)) modifica il valore della variabile a, il cui valore modificato può essere utilizzato successivamente.

Output dello script: Mostra codice

I materiali di supporto della lezione

Bash guide for beginners: Cap 1 (par. 1-3); Cap 2 (par. 1-2); Cap 3 (par. 1-4); Cap 10 (par. 2-3)

Advanced Bash Scripting: capitoli 2, 3, 4, 5, 6, 8, 11, 12

  • Contenuti protetti da Creative Commons
  • Feed RSS
  • Condividi su FriendFeed
  • Condividi su Facebook
  • Segnala su Twitter
  • Condividi su LinkedIn
Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion