Modulo 2:
La shell

Laboratorio di Sistemi Operativi I

Anno Accademico 2005-2006

Francesco Pedullà

(Tecnologie Informatiche)

Massimo Verola

(Informatica)

Copyright © 2005 Francesco Pedullà, Massimo Verola

Copyright © 2001-2005 Renzo Davoli, Alberto Montresor (Universitá di Bologna)

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license can be found at: http://www.gnu.org/licenses/fdl.html#TOC1

La shell di Linux

E' un programma che si interpone fra l’utente e il SO (deve il suo nome al fatto che nasconde dietro la sua interfaccia i dettagli del SO sottostante )

Ha la funzione di interprete della linea comandi ed esecutore di comandi su richiesta dell'utente

Presenta all'utente il prompt (una stringa personalizzabile, per convenzione terminata dal carattere % o $ o >) dopo il quale l'utente digita i comandi da sottomettere al sistema

E' programmabile: permette di scrivere delle procedure in un linguaggio interpretato detto script

Per analogia, le interfacce grafiche disponibili per Linux (quali KDE, GNOME) sono a volte identificate come shell grafiche o visuali

Esistono diversi tipi di shell

Bourne shell (sh)

Korn shell (ksh)

C shell (csh, tcsh)

Bash (Bourne-again shell) (bash)

Quale shell scegliere?

Questione di gusti…

Bash è la più diffusa in ambiente Linux

Studio della shell

Caratteristiche comuni (common core)

Analisi della bash

Tipi di shell

bash

korn

bourne

c shell

common
core

tcsh

Caratteristiche delle Shell

Sommario:

Comandi interni

Metacaratteri

Redirezione dell’I/O

Pipes

Wildcards

Command substitution

Sequenze

Condizionali

Non condizionali

Raggruppamento di comandi

Esecuzione in background

Quoting

Sub-shell

Variabili

Locali

Di ambiente

Script

Meccanismo di funzionamento

Quando l'utente digita una linea di comando e la sottomette alla shell mediante il tasto <RETURN>, la shell estrae innanzitutto la prima parola

Assumendo che sia il nome di una programma, lo ricerca nel filesystem (a meno che non sia un comando interno) e lo manda in esecuzione

Quindi si sospende fino alla terminazione del programma, dopo la quale assume di nuovo il controllo e visualizza il prompt, in attesa del prossimo comando

Da notare che la shell è un ordinario programma che viene eseguito nello spazio utente, che legge/scrive da/su terminale e che ha la capacità di lanciare altri programmi

Comandi

rappresentano una richiesta di esecuzione

sintassi generale: comando opzioni argomenti

gli argomenti indicano l'oggetto su cui eseguire il comando

le opzioni (generalmente!)

iniziano con - (seguito da una
lettera) o -- (seguito da una parola)

modificano l'azione del comando

Esempi di comandi:

comandi interni della shell

script interpretati

programmi eseguibili

Tasti di controllo nella shell

Ctrl-S sospende la visualizzazione

Ctrl-Q riattiva la visualizzazione

Ctrl-C interrompe il processo

Ctrl-Z sospende il processo

Ctrl-D end-of-file

Comandi interni ed esterni

Interni, o built-in

Il comando viene riconosciuto ed eseguito direttamente dalla shell.

Esempi:

echo	# displays all of its arguments to standard output

cd	# change directory

Esterni

Il corrispondente file eseguibile viene cercato, caricato in memoria ed eseguito.

Esempio: il comando ls si trova in /bin/ls

Metacaratteri

Caratteri speciali

>, >>, <	redirezione I/O

|	pipe

*, ?, […]	wildcards

‘command‘	command substitution

;	esecuzione sequenziale

||, &&	esecuzione condizionale

(…)	raggruppamento comandi

&	esecuzione in background

"", ’’	quoting

#	commento

$	espansione di variabile

\	carattere di escape

<<	“here documents”

Selezionare una shell

Quando vi viene fornito un account UNIX, una shell di default viene selezionata per voi

Per vedere che shell state utilizzando:

% echo $SHELL # display the content of variable SHELL

Per cambiare shell:

% chsh [<username>] # asks for the full pathname of the new shell

[penguin@artarctic ~]$ echo $SHELL

/bin/bash

[penguin@artarctic ~]$ chsh

Changing shell for penguin.

Password:

New shell [/bin/bash]: /bin/tcsh

Shell changed.

[penguin@artarctic ~]$

Subshells

Quando aprite un terminale, viene eseguita una shell

Viene creata una child shell (o subshell)

Quando viene eseguito uno script

Quando viene eseguito un processo in background

Nel caso di comandi raggruppati, come ( date; ls ; pwd )

Caratteristiche delle subshell:

Hanno la propria directory corrente:

% (cd / ; pwd)
/
% pwd
/home/penguin

Due distinte aree di variabili vengono gestite differentemente
(vedi dopo)

Variabili

Ogni shell supporta due tipi di variabili:

Variabili locali: non ereditate dalle subshell create dalla shell

Utilizzate per elaborazioni locali all’interno di uno script

Variabili di ambiente: ereditate da una shell alle subshell create da essa

Utilizzate per comunicazioni da parent a child shell

Entrambe le variabili contengono dati di tipo stringa

Ogni shell ha alcune variabili di ambiente inizializzate da file di startup o dalla shell stessa

$HOME, $PATH, $MAIL, $USER, $SHELL, $TERM, etc.

Per visualizzare l’elenco completo, usate il comando env

Utilizzo delle variabili

Per accedere al contenuto di una variabile:

Utilizzate il metacarattere $

$name è la versione abbreviata di ${name}, da usare solo quando non vi siano ambiguità nell'interpretazione

se si vuole estrarre una sottostringa: ${name:start:len}

Per assegnare un valore ad una variabile:

Sintassi diversa a seconda della shell

Nel caso di bash

nome=valore	# problem with spaces
nome="il valore"	# no problem with spaces

Variabili dichiarate in questo modo sono locali

Per trasformare una variabile locale in una d’ambiente, usate il comando export

% export nome

Ancora sulle sottostringhe

E' possibile eliminare la più lunga o la più breve sottostringa iniziale:

% myvar=”foodforthought”

% echo ${myvar##*fo}

rthought

% echo ${myvar#*fo}

odforthought

E' possibile eliminare la più lunga o la più breve sottostringa finale:

% myvar=”foodforthought”

% echo ${myvar%%fo*}

% echo ${myvar%fo*}

food

Esercizi

Prevedere l'output del sistema in questa sequenza di comandi:

% firstname=“Penguin”

% lastname=“Blackwhite”

% echo $firstname $lastname

% export firstname

% bash

% echo $firstname $lastname

% firstname=“Zebra”

% exit

% echo $firstname $lastname

Sia myvar='prova1' e si voglia creare la nuova variabile myvar2 con valore 'abcprova1def': quale sintassi usare per l'assegnazione?

Sia myvar='unoduetre' e si voglia creare tre variabili contenenti rispettivamente 'uno' 'due' 'tre': come estrarle da myvar?

Redirezione dell’input/output e pipes

Ogni processo è associato a tre stream (flussi di byte)

Standard output (stdout)

Standard input (stdin)

Standard error (stderr)

Redirezione dell’I/O e pipe permettono:

“Disconnettere” questi stream dalle loro sorgenti/destinazioni abituali

“Connetterli” ad altri sorgenti / destinazioni

Process
P

stdin

stdout

stderr

terminal
input

terminal
output

Redirezione dell’input/output

Usi della redirection

Salvare l’output di un processo su un file (output redirection)

Usare il contenuto di un file come input di un processo

Esempi:

Salva l’output di ls in list.txt

ls > list.txt

Aggiunge (append) l’output di ls a list.txt

ls >> list.txt

Spedisce il contenuto di list.txt a penguin@antarctic.org

mail penguin@antarctic.org < list.txt

Redireziona stdout e stderr del comando rm al file /dev/null

rm file >& /dev/null

mail penguin@antarctic.org < list.txt

ls > list.txt

Nota:
esistono esempi di redirezione più complessi; consultate
info bash per i dettagli

Redirezione dell’input/output

Process
mail

stdin

stdout

stderr

list.txt

terminal
output

Process
ls

stdout

stderr

list.txt

terminal output

Pipes

Pipe, o catena di montaggio:

La shell vi permette di usare lo standard output di un processo come standard input di un altro processo

Esempio:

% ls
a b c d f1 f2

% ls | wc –w

6

Usage: tee –ia <pathname>

Copia il contenuto dello standard input sul file specificato e sullo standard output; -a esegue l’append

il nome tee deriva dai “giunti a T” usati dagli idraulici

Esempio:

% who | tee who.capture | sort

Process
wc

stdin

stdout

stderr

terminal
output

Process
ls

stdout

stderr

Wildcards

Utilizzati per specificare file pattern

La shell sostituisce la stringa contenente wildcards con l’elenco dei file che soddisfano la condizione

Caratteri speciali:

*	matching di qualsiasi stringa

?	matching di qualsiasi carattere singolo

[…]matching di qualsiasi carattere inserito nelle parentesi

Esempi:

*.c

prova00?.c

prova[0-9][0-9][0-9].txt

Esercizi

Spiegare in dettaglio come la shell tratta il seguente comando:
mail penguin@antarctic.org < list.txt

Scrivere un comando che emuli il comando ls *file* senza usare il comando ls

Il comando grep PATTERN [FILE ...] cerca nei file indicati l’espressione regolare PATTERN e stampa solo le linee che la contengono; esiste anche l’opzione -R che permette di cercare PATTERN ricorsivamente nei file della directory indicata e in tutte le subdirectory ricorsivamente; scrivere un comando che emuli grep -R PATTERN DIR, utilizzando grep (ed altri comandi) ma senza ricorrere all’opzione -R (suggerimento: comporre grep con find o xargs).

Sequenze (condizionali e non)

Sequenze non condizionali

Il metacarattere ; viene utilizzato per eseguire due comandi in sequenza

Esempio:

% date ; pwd ; ls

Sequenze condizionali

|| viene utilizzato per eseguire due comandi in sequenza, solo se il primo ha un exit code uguale a 1 (failure)

&& viene utilizzato per eseguire due comandi in sequenza, solo se il primo ha un exit code uguale a 0 (success)

Esempi:

% gcc prog.c && a.out
% gcc prog.c || echo Compilazione fallita

Raggruppamento di comandi

E’ possibile raggruppare comandi racchiudendoli dentro delle parentesi

Vengono eseguiti in una subshell dedicata

Condividono gli stessi stdin, stdout e stderr

Esempi:

% date ; ls ; pwd > out.txt

% (date ; ls ; pwd) > out.txt

Esecuzione in background

Se un comando è seguito dal metacarattere &:

Viene creata una subshell

il comando viene eseguito in background, in concorrenza con la shell che state utilizzando

non prende il controllo della tastiera

utile per eseguire attività lunghe che non necessitano di input dall’utente

Esempi:

% find / -name passwd –print &
20123
% /etc/passwd

% find / -name passwd –print &> results.txt &
20124

Command substitution

Gli apici ‘ ‘ sono utilizzati per fare command substitution

Il comando racchiuso fra apici viene eseguito, e il suo standard output viene sostituito al posto del comando

Esempi:

% echo Data odierna: ‘date‘

% echo Utenti collegati: ‘who | wc -l‘

% tar zcvf src-‘date‘.tgz src/

Sintassi alternativa con $(...):
% today=$(date)

Quoting

Esiste la possibilità di disabilitare wildcard / command substitution / variable substitution

Single quotes ’ inibiscono wildcard, command substitution, variable substitution

Esempio:

% echo 3 * 4 = 12

% echo ’3*4 = 12’

Double quotes “ inibiscono wildcard e basta

Esempio:

% echo “ my name is $name – date is ‘date‘ ”

% echo ’ my name is $name – date is ‘date‘ ’

Help in linea

Fare riferimento alla documentazione on-line

man command

info command

apropos keyword

Per informazioni sull'utilizzo di man ed info:

man man

info

Esercizi

Qual'é l’effetto del comando sort file > file, dove file é il nome di un file? E quello del comando sort file >> file ?

Fare alcuni esperimenti per scoprire qual é l’effetto del comando tr str1 str2 se le stringhe str1 e str2 hanno lunghezze diverse. Scrivere un comando per sostituire tutti i caratteri alfanumerici nell’input con un carattere <Tab>, in modo che non compaiano più <Tab> consecutivi.

Il comando date fornisce data e ora su standard output. Studiarne la sintassi per estrarre soltanto l'ora.

Estrarre da /etc/passwd il primo campo della prima riga (suggerimento: usare il comando head per estrarre la prima riga).

Alberto Montresor

2003-09-08T07:38:59

Alberto Montresor