Sistemi Operativi – La shell Salvatore Campagna Email: [email protected] Politecnico di Torino Dipartimento di Automatica e Informatica La shell - Instroduzione Lo strato più esterno del Sistema Operativo In UNIX/Linux la shell non è parte del sistema operativo ma è un normale processo utente Utilizzata per impartire comandi La shell - Introduzione In UNIX esistono diverse shell ◦ ◦ ◦ ◦ ◦ Bourne Shell (sh) C-shell (csh) Korn shell (ksh) Tahoe C-shell (tcsh) Bourne Again Shell (bash) La shell - Instroduzione All’avvio della shell vengono eseguiti i comandi contenuti in due file: 1. /etc/profile: per i comandi globali 2. ~/.profile: comandi per il singolo utente Alcune eseguono anche i comani contenuti nel file .logout quando terminano Avvio shell Bash Per la shell Bash i file sono: ◦ Shell di login: /etc/profile e poi dalla propria home .bash_profile, .bash_login, .profile (di questi ultimi tre verrà letto solo il primo file esistente) ◦ Shell di login: .bash_logout, questo file viene letto all'uscita dalla shell ◦ Interattiva: .bashrc Caratteristiche della shell Parametri Completamento automatico Pipe (o Pipeline) Redirezione dell’I/O History Aliasing Espansione dei comandi La shell – I parametri Simili a variabili di un linguaggio di programmazione Memorizzano uno o più valori Non hanno un tipo Possono avere un nome ($n, $nome, $address,…) Posizionali ($1, $2, …) se si riferiscono a parametri passati a un programma sulla riga di comando La shell – Parametri speciali $0: nome del comando in esecuzione $#: numero di parametri posizionali sulla riga di comando $?: exit stats dell’ultimo comando $$: process ID della shell corrente $!: process ID dell’ultimo comando eseguito in background $-: opzioni passate alla shell corrente $*: una stringa contenente tutti i parametri posizionali ($1, $2, …) $@: come $* La shell – Le variabili Assegnazione: nome=“Alice”, max=“10” ATTENZIONE: non inserire spazi tra “=“ e ‘”’ export nome: rende la variabile nome visibile ad altri processi unset nome: cancella la variabile e il suo valore La shell – Le variabili Variabili built-in: ◦ PATH: variabile che indica le directory in cui cercare i comandi ◦ HOME: variabile che punta alla home directory dell’utente ◦ BASH_ARGV, BASH_ARGC: parametri e numero di parametri passati alla shell Vettori ◦ vett[1]=‘’uno’’, vett[2]=‘’due’’ ◦ v=(uno due tre quattro) La shell – visualizzazione di variabili Si deve precedere il nome della variabile con il simbolo ‘$’ Esempi: ◦ echo $nome visualizza il contenuto della variabile nome ◦ echo ${vett[2]} visualizza il contenuto dell’elemento con indice ‘2’ del vettore vett La shell – Completamento automatico Il tasto TAB permette di espandere e completare nomi di file, variabili e comandi: ◦ Se la riga comincia con $ la shell cerca di completare con un nome di variabile ◦ Altrimenti cerca di completare la riga con un comando ◦ In fine cerca di completare con il nome di un file ordinario della directory corrente La shell - Pipe Concatenazione di più comandi in modo tale che lo stdout di un processo diventi lo stdin di un altro processo stdin(0) proc1 stderr(2) stdout(1) stdin proc2 stdout stderr La shell - Pipe Sintassi: comando1 | comando2 L’output di comandi1 diventa l’input di comando2 Esempi: ◦ ls –la | more ◦ cat /etc/passwd | sed ‘s/bash/csh/g’ ◦ cat /etc/passwd | grep “alice” La shell – Redirezione dell I/O E’possibile redirigere stdout, stdin e stderr di un processo su file comando < file: redirige lo stdin di comando in modo che l’input sia letto da file comando > file: redirige lo stdout di comando in modo che scriva su file Esempio: cat /etc/passwd | grep “alice” > alice_data.txt La shell – Redirezione dell’I/O comando >> file: redirige lo stdout di comando in modo che venga scritto su file in modalità append (non cancella i dati presenti) comando << file: redirige lo stdin di comando in modo che venga letto da HERE DOCUMENT Esempio: ◦ $ tr a-z A-Z <<END_TEXT ◦ > one two three ◦ > uno dos tres ◦ > END_TEXT ◦ ONE TWO THREE ◦ UNO DOS TRES La shell – Redirezione dell’I/O comando &> file: redirige stderr e stdout di comando su file comando 2> file: redirige stderr su file comando 1> file: redirige stdout su file (come comando > file) comando 1> filea 2>fileb: redirige stdout e stderr su file diversi La shell redirezione dell’I/O /dev/null è un file virtuale con la caratteristica di scartare (non memorizzare) tutti i dati che gli vengono scritti comando > /dev/null: scrive scartando i dati di output comando < /dev/null: legge un end-of-file EOF comando 2> /dev/null: ignora i messaggi di errore La history : mostra i comandi eseguiti precedentemente history: visualizza tutti I comandi eseguiti su due colonne con <numero comando> <comando> Si può fare riferimento a un comando contenuto nella history attraverso il suo numero La history !n: esegue il comando n ◦ Se n è negativo esegue l’n-ultimo comando !<stringa>: esegue l’ultimo comando che comincia con <stringa> !!:s/<old>/<new>: rimpiazza la prima occorrenza di <old> nell’ultimo comando con <new> CTRL-r: entra in modalità di ricerca Aliasing E’ possibile definire nuovi nomi da associare a un comando Il nuovo nome è un alias Il comando alias senza parametri visualizza gli alias definiti per la shell corrente alias <alias>= ‘’valore’’ definisce un nuovo alias unalias <alias>: cancella l’alias con nome <alias> Aliasing Esempi: ◦ ◦ ◦ ◦ ◦ alias ll = ‘’ls –l’’ alias rm = ‘’rm –i’’ alias cd.. = ‘’cd ..’’ alias dir = ‘’ls –l’’ alias vi=‘’vim’’ Sono validi nella shell corrente Se inseriti in /home/<user>/.bashrc gli alias vengono definiti all’avvio della shell Espansione dei comandi La shell esegue una serie di espansioni o sostituzioni in un comando Esempio: ls $HOME La shell espande (o sostituisce) la variabile $HOME con il suo contenuto Il comando eseguito diventa ls /home/alice Espansione dei comandi Il quoting serve a evitare l’espansione Ci sono tre modi per fare quoting ◦ Usare il carattere ‘\’: preserva il valore letterale del carattere che segue ◦ Gli apici singoli ‘ ‘: preservano il valore letterale del loro contenuto ◦ Gli apici doppi: come precedenti ma escluso $, $() e \ Espansione dei comandi La shell esegue l’espansione in un ordine ben preciso dopo aver analizzato la riga di comando Brace Expansion: viene sostituito prima il contenuto delle parentesi graffe (se non quotate) ◦ Esempio: cat file{1,2,3}.txt viene sostituito da cat file1.txt file2.txt file3.txt Tilde Expansion: viene espanso i carattere tilde ~ (se non quotate) ◦ Esempio: cat ~/file.txt viene espanso in cat /home/alice/file.txt Espansione dei comandi Parameter Expansion: si sostituisce il parametro col suo valore ◦ Esempio: dir=‘’/tmp’’; find $dir –name ‘’*.c’’ viene espanso in find /tmp -name ‘’*.c’’ Command Expansion: si sostituisce con l’output del comando ◦ Esempio: cat $(find . –name ‘’*.c’’) viene espanso in cat main.c file1.c file2.c Supponendo che la directory corrente contenga i file main.c file1.c e file2.c Espansione dei comandi Arithmetic Expansion: viene espanso il risultato di una operazione aritmetica ◦ Esempio: echo $((2*3+1)) viene espanso in echo 7 Word Splitting: la riga di comando viene suddivsa in parole Espansione dei comandi Filename expansion: vengono sostituiti i nomi di file in corrispondenza di espressioni contenenti *, ? E [...] ◦ Esempio: cat *.c viene espanso in cat main.c file1.c file2.c (* = qualsiasi stringa) ◦ Esempio: cat file?.c viene espanso in cat file1.c file2.c (? = qualsiasi carattere singolo) ◦ Esempio: cat file[ab].c espanso in cat filea.c fileb.c ([ ] = qualsiasi carattere tra parentesi) Supponendo che la directory corrente contenga i file main.c file1.c e file2.c Espansione dei comandi Quote Removal: tutte le occorrenze non quotate dei caratteri \ ‘ e ‘’ vengono rimossi a meno che queste non siano il risultato di una espansione ◦ Esempio echo ‘Hello World’ espanso in echo Hello World ◦ Esempio: var=‘ ’’hello’’ ‘ l’espansione di echo $var da come risultato echo ‘’hello’’ ◦ Gli apici doppi sono il risultato della parameter expansion della variabile var e quindi non vengono rimossi quando viene eseguito il quote removal Esempio Come vengono espansi i seguenti comandi? ◦ so_es=‘’ ~/so_es ‘’ ◦ backup_dir=‘’backup_$(date)’’ ◦ mkdir -p $so_es/”$backup_dir” ◦ cp –r ~/so_es1/*.{c,h} ~/so_es1/”$backup_dir”