ShellLa shell, che sta tra l'utente e il sistema operativo, opera come un
interprete di comandi. Legge l'input dal terminale e traduce i comandi in
azioni, azioni che vengono intraprese dal sistema. La shell è simile
al command.com in DOS. Una volta effettuato il login
nel sistema, viene assegnata la shell di default. La shell, al suo avvio,
legge i suoi file di inizializzazione e può settare alcune
variabili di ambiente, i path di ricerca dei comandi, gli alias dei comandi
ed eseguire qualche comando specificato in questi file.La prima shell è stata la shell Bourne, &man.sh.1;. Ogni
piattaforma Unix dispone della shell Bourne o di una shell Bourne
compatibile. Questa shell ha molte buone caratteristiche per controllare
l'input e l'output, ma non è molto adatta all'utente interattivo.
Per andare incontro a quest'ultimo è stata scritta la shell C,
&man.csh.1;, presente ora in molti, ma non tutti, i sistemi Unix.
Questa shell usa una sorta di sintassi C, il linguaggio con cui Unix
è stato scritto, ma ha molte scomode implementazioni
dell'input/output. La shell C ha il controllo dei job, quindi può
mandare un job eseguito in background (sotto shell) in
foreground (in shell corrente). Inoltre ha la funzione di
history (storia dei comandi) che permette di modificare e ripetere comandi
eseguiti precedentemente.Il prompt di default per la shell Bourne è $
(o &prompt.root; per l'utente root). Il prompt di default per la shell C
è &prompt.user;.Sono disponibili in rete molte altre shell. Quasi tutte sono basate
sulla shell &man.sh.1; o &man.csh.1; con estensioni per fornire il controllo
dei job alla shell &man.sh.1;, permettere di manipolare il modo di
esecuzione dei comandi su linea di comando, cercare attraverso i comandi
eseguiti precedentemente, fornire il completamento dei nomi dei comandi,
prompt personalizzati, ecc. Alcune delle seguenti shell maggiormente
conosciute potrebbero essere sul proprio amato sistema Unix: la shell korn,
ksh, di David Korn e la shell Bourne Again, &man.bash.1;,
dal progetto GNU Free Software Foundations, entrambe basate su &man.sh.1;,
la shell T-C, &man.tcsh.1; e l'estensione della shell C,
cshe, entrambe bastate su &man.csh.1;. In seguito si
descriveranno alcune delle caratteristiche di &man.sh.1; e &man.csh.1;,
così per iniziare.Comandi built-inLa shell ha alcuni comandi built-in, chiamati
anche comandi nativi. Questi comandi sono eseguiti direttamente dalla
shell e non chiamano nessun altro programma per essere eseguiti. Questi
comandi built-in possono essere diversi tra le varie shell.ShPer la shell Bourne alcuni dei comandi built-in più
comunemente usati sono::comando null.prende (legge ed esegue) i comandi da un filecasecondizionale casecdcambia la directory di lavoro ($HOME di
default)echoscrive una stringa su standard outputevalvaluta l'argomento specificato e ritorna il risultato alla
shellexecesegue il comando specificato rimpiazzando la shell
correnteexitesce dalla shell correnteexportcondivide le variabili di ambiente specificate con le
successive shellforcondizionale di ciclo forifcondizionale ifpwdmostra la directory di lavoro correntereadlegge una linea di input da standard inputsetsetta le variabili di shelltestvaluta un'espressione come vera o falsatrapintrappola un tipo di segnale ed esegue comandiumasksetta la maschera di default relativa ai permessi da
impostare per i nuovi fileunsetresetta le variabili di shellwaitattente che un specifico processo terminiwhilecondizionale di ciclo whileCshPer la shell C i comandi built-in maggiormente usati sono:aliasassegna un nome a una funzionebgmette un job in backgroundcdcambia la directory di lavoro correnteechoscrive una stringa su standard outputevalvaluta gli argomenti specificati e ritorna il risultato
alla shellexecesegue il comando specificato rimpiazzando la shell
correnteexitesce dalla shell correntefgporta un job in foregroundforeachcondizionale di ciclo forglobcrea un'espansione dei nomi di file su una lista senza
tenere conto del carattere di escape \historystampa la storia dei comandi della shellifcondizionale ifjobsmostra o controlla i job attivikilltermina un processo specificolimitsetta dei limiti sulle risorse di sistemalogouttermina la shell di loginnice
comandoabbassa la priorità di schedulazione del
comando specificatonohup
comandonon termina il comando specificato quando la shell
escepopdestrae un record dallo stack delle directory e ritorna
nella directory estrattapushdcambia nella nuova directory specificata e aggiunge quella
corrente nello stack delle directoryrehashricrea la tabella hash dei percorsi (path) per i file
eseguibilirepeatripete un comando il numero di volte specificatosetsetta una variabile di shellsetenvsetta una variabile di ambiente per la shell corrente e per
quelle successivesourceprende (legge ed esegue) comandi da un filestopferma uno specifico job in backgroundswitchcondizionale switchumasksetta la maschera di default relativa ai permessi da
impostare per i nuovi fileunaliasrimuove il nome alias specificatounsetresetta le variabile di shellunsetenvresetta le variabili di ambientewaitattente la terminazione di tutti i processi in
backgroundwhilecondizionale di ciclo whileVariabili di ambienteLe variabili di ambiente sono usate per fornire informazioni ai
programmi che si utilizzano. Si possono avere sia variabili
globali di ambiente sia variabili locali di
shell. Le variabili globali di ambiente sono inizializzate
attraverso la propria shell di login e i nuovi programmi e le nuove shell
ereditano l'ambiente della shell genitore. Le variabili locali di shell
sono usate solamente dalla shell corrente e non sono passate ad altri
processi. Un processo figlio non può passare una variabile al suo
processo padre.Le variabili di ambiente correnti sono visualizzabili con i comandi
&man.env.1; o &man.printenv.1;. Alcune comuni variabili sono:DISPLAYIl display grafico da usare, esempio
nyssa:0.0EDITORIl path (percorso) del proprio editor di default, esempio
/usr/bin/viGROUPIl proprio gruppo di login, esempio
staffHOMEIl path della propria home directory, esempio
/home/frankHOSTIl nome host del proprio sistema, esempio
nyssaIFSI separatori di campo interni, generalmente alcuni spazi
bianchi (tab, spazio e new-line di default)LOGNAMEIl nome del proprio login, esempio
frankPATHI path per ricercare i comandi, esempio
/usr/bin:/usr/ucb:/usr/local/binPS1La stringa del prompt primario, solamente shell Bourne
($ di default)PS2La stringa del prompt secondario, solamente shell Bourne
(> di default)SHELLLa propria shell di login, esempio
/usr/bin/cshTERMIl proprio tipo di terminale, esempio
xtermUSERIl proprio username, esempio
frankMolte variabili di ambiente sono inizializzate automaticamente quando
si effettua il login. Queste possono essere modificate e si possono
definire altre variabili nei propri file di inizializzazione o in
qualunque momento all'interno della shell. Alcune variabili che è
possibile si voglia cambiare sono PATH e
DISPLAY. La variabile PATH
specifica le directory nelle quali saranno automaticamente cercati i
comandi richiesti. Alcuni esempi sono nello script di inizializzazione
di shell mostrato più avanti.Per la shell C si può settare una variabile globale
di ambiente con un comando simile a quello usato per
visualizzare le variabili:&prompt.user; setenv NOME valoree per la shell Bourne:$ NOME=valore; export NOMESi possono elencare le proprie variabili globali di ambiente con i
comandi &man.env.1; o &man.printenv.1;. Si possono resettare queste
variabili con i comandi unsetenv (shell C) o
unset (shell Bourne).Per settare una variabile locale di shell in
shell C si usa il comando set con la sintassi seguente.
Senza opzioni set mostra tutte le variabili
locali.&prompt.user; set nome=valorePer la shell Bourne si setta una variabile locale di shell
con:$ nome=valoreIl valore corrente di una variabile è accessibile attraverso le
notazioni $nome o
${nome}.La shell Bourne, shLa shell &man.sh.1; usa il file di inizializzazione
.profile posto nella home directory dell'utente.
Inoltre può esserci un file di inizializzazione globale del
sistema, esempio /etc/profile. In tal caso, il file
globale del sistema sarà eseguito prima di quello locale.Un semplice file .profile potrebbe essere come
il seguente:
PATH=/usr/bin:/usr/ucb:/usr/local/bin:. # setta il PATH
export PATH # rende disponibile PATH per le sotto-shell
# setta il prompt
PS1="{`hostname` `whoami`} " # setta il prompt, $ di default
# funzioni
ls() { /bin/ls -sbF "$@";}
ll() { ls -al "$@";}
# setta il tipo di terminale
stty erase ^H # setta Control-H come tasto di cancellazione
eval `tset -Q -s -m ':?xterm'` # richiede il tipo di terminale, presupponendo
# xterm
#
umask 077Ogni volta che si incontra il simbolo #, il resto di quella linea
viene trattato come un commento. Nella variabile PATH
ogni directory è separata da due punti (:) e il punto
(.) specifica che la directory corrente è nel
proprio path. Se il punto non è nel proprio path, lo stesso
diventa un semplice elemento per eseguire un programma nella directory
corrente:./programmaNon è una buona idea avere il punto (.)
nel proprio PATH, in modo tale da non eseguire
inavvertitamente un programma senza averne l'intenzione quando si usa il
comando cd per spostarsi in differenti
directory.Una variabile settata in .profile rimane valida
solo nel contesto della shell di login, a meno che la si esporti con
export o si esegua .profile in
un'altra shell. Nell'esempio precedente PATH viene
esportato per le sotto-shell. Si può eseguire un file con il
comando built-int . di &man.sh.1;, esempio:. ./.profileSi possono creare proprie funzioni. Nell'esempio precedente la
funzione ll, risultato di ls -al,
lavora su un specifico file o directory.Con &man.stty.1; il carattere di cancellazione viene settato a
ControlH, che è usualmente il tasto di
Backspace.Il comando &man.tset.1; richiede il tipo di terminale e assume questo
a xterm se si conferma con invio
<CR>. Questo comando è eseguito con un
comando built-in di shell, eval, che prende il
risultato del comando &man.tset.1; e lo usa come argomento per la shell.
In questo caso l'opzione di &man.tset.1; setta
le variabili TERM e TERMCAP e le
esporta.L'ultima linea nell'esempio richiama il comando
umask, facendo in modo che i file e le directory create
non abbiano i permessi di lettura-scrittura-esecuzione per l'utenza
gruppo e altri.Per altre informazioni su &man.sh.1;, digitare
man sh al prompt di shell.La shell C, cshLa shell C, &man.csh.1;, usa i file di inizializzazione
.cshrc e .login. Alcune
versioni usano un file di inizializzazione globale del sistema, ad
esempio /etc/csh.login. Il proprio file
.login è eseguito solamente quando si effettua
il login. Il proprio file .cshrc è eseguito
ogni volta in cui si avvia una shell &man.csh.1;, incluso quando si
effettua il login. Questo file ha molte caratteristiche simili al file
.profile, ma un differente modo di composizione.
Qui si usano i comandi set o setenv
per inizializzare una variabile, dove set viene usato
per definire una variabile solo per la shell corrente, mentre
setenv definisce una variabile per la shell corrente e
per le altre sotto-shell. Le variabili di ambiente
USER, TERM e PATH
sono automaticamente importate ed esportate dalle variabili
user, term e path
della shell &man.csh.1;. Quindi setenv non è
necessario per queste variabili. La shell C usa il simbolo ~ per indicare
la directory home dell'utente in un path, come in
~/.cshrc o per specificare una directory di login di
un altro utente, come in
~username/.cshrc.Alcune variabili predefinite usate dalla shell C sono:argvLa lista degli argomenti della shell correntecwdLa directory di lavoro correntehistoryImposta la dimensione della lista di history (storia) da
memorizzarehomeLa directory home dell'utente, visualizzabile con
$HOMEignoreeofQuando viene settata, EOF (CtrlD) viene ignorato dal terminalenoclobberQuando viene settata si impedisce di redirigere l'output per
sovrascrivere file esistentinoglobQuando viene settata si impedisce l'espansione dei nomi di
file all'interno di un confronto con uno schema wild cardpathI path di ricerca dei comandi, visualizzabile con
$PATHpromptSetta il prompt della linea di comando (&prompt.user; di
default)savehistNumero di volte (di login) che bisogna mantenere memorizzata
la lista di history nel file .historyshellIl path name completo della shell corrente, visualizzabile
con $SHELLstatusIl codice di stato di uscita dell'ultimo comando
(0=uscita normale, 1=comando fallito)termIl proprio tipo di terminale, visualizzabile con
$TERMuserIl proprio nome utente, username, visualizzabile con
$USERUn semplice file .cshrc potrebbe essere come il
seguente:
set path=(/usr/bin /usr/ucb /usr/local/bin ~/bin . ) # setta il path
set prompt = "{`hostname` `whoami` !} " # setta il promt primario ;
# % di default
set noclobber # non redirige l'output su file esistenti
set ignoreeof #ignora EOF (Ctrl+D) in questa shell
set history=100 savehist=50 # mantiene una lista history di comandi e la
# memorizza tra vari (50) login
# alias
alias h history # alias h per history
alias ls "/usr/bin/ls -sbF" # alias ls per ls -sbF
alias ll ls -al # alias ll per ls -sbFal (combina queste
# opzioni con quelle di ls sopra citate)
alias cd 'cd \!*;pwd' # alias cd per stampare la directory di lavoro
# corrente dopo aver cambiato directory
umask 077Alcune nuove caratteristiche che non sono state viste nel
file .profile (shell &man.sh.1;) sono
noclobber, ignoreeof e
history. Noclobber indica che
l'output non può essere rediretto su un file esistente, mentre
ignoreeof specifica che EOF (
CtrlD) non causa l'uscita dalla shell di login o l'uscita dal
sistema.Con la caratteristica di history si possono
richiamare comandi eseguiti precedentemente e rieseguirli, eventualmente
con dei cambiamenti.Un alias permette di usare uno specifico nome
alias al posto del comando completo. Nell'esempio
precedente, il risultato di digitare ls sarà
quello di eseguire /usr/bin/ls -sbF. Si può
verificare quale comando ls è nel proprio path
con il comando &man.which.1;, ad esempio:&prompt.user; which ls
ls: alias di /usr/bin/ls -sbFUn semplice file .login potrebbe essere come il
seguente:# .login
stty erase ^H # setta Control+H come tasto di eliminazione
set noglob # impedisce un confronto con uno schema wild card
eval `tset -Q -s -m ':?xterm'` # chiede il tipo di terminale presupponendo
# xterm
unset noglob # riabilita un confronto con uno schema wild cardAbilitando e disabilitando noglob intorno a
&man.tset.1; si impedisce di confondere il tipo di terminale con
qualche espansione dei nomi di file in un confronto con uno schema
(pattern) wild card.Se si effettuano cambiamenti al proprio file di inizializzazione,
questi possono essere attivati eseguendo il file modificato. Per la shell
&man.csh.1; questo è possibile attraverso il comando
built-in source, esempio:source .cshrcPer altre informazioni circa la shell &man.csh.1; digitare
man csh al prompt di shell.Controllo dei jobCon la shell C, &man.csh.1; e molte altre nuove shell, incluse alcune
nuove shell Bourne, si possono mettere i job in background apporrendo
& al comando, così come succede per la
shell &man.sh.1;. Questo può anche essere fatto, una volta
sottoposto il comando, digitando ControlZ per sospendere il job e quindi bg per
metterlo in background. Per riportarlo in foreground si digita
fg.Si possono avere molti job eseguiti in background. Quando questi sono
in background, non sono connessi alla tastiera per l'input, ma possono
tuttavia mostrare l'output nel terminale, sparpagliandolo con qualsiasi
cosa ci sia digitata o mostrata attraverso il job corrente. Si può
avere la necessità di redirigere I/O in o da un file per un job in
background. La propria tastiera è solamente connessa al corrente
job in foreground.Il comando built-in jobs permette di elencare i
propri job in background. Si può usare il comando &man.kill.1; per
terminare un job in background. In questi comandi, con la notazione
%n ci si riferisce
all'n-esimo job in background, rimpiazzando
n con il numero di job proveniente dall'output
di jobs. Quindi si termina il secondo job in
background con kill %2 e si riprende il terzo job in
foreground con fg %3.HistoryLa shell C, la shell Korn e molte altre shell avanzate, mantengono
informazioni sui comandi che sono stati eseguiti in shell. La
quantità di storia memorizzabile dipende dalla shell utilizzata.
Qui si descriveranno le caratteristiche di history della shell C.Si possono usare le variabili history e
savehist per settare rispettivamente quanti comandi
della shell corrente memorizzare e per quanti login mantenerli.
Si può inserire in .cshrc la seguente linea
per memorizzare 100 comandi della shell corrente fino a 50 prossimi
login.set history=100 savehist=50La shell mantiene traccia della storia dei comandi tra un login e
l'altro memorizzandola nel file ~/.history.Si può usare il comando built-in history per
richiamare i comandi eseguiti precedentemente, ad esempio per stampare gli
ultimi 10:&prompt.user; history 10
52 cd workshop
53 ls
54 cd Unix_intro
55 ls
56 pwd
57 date
58 w
59 alias
60 history
61 history 10Si può ripetere l'ultimo comando digitando
!!:&prompt.user; !!
53 ls
54 cd Unix_intro
55 ls
56 pwd
57 date
58 w
59 alias
60 history
61 history 10
62 history 10Si può ripetere un comando numerato introducendo il numero con
un !, esempio:&prompt.user; !57
date
Tue Apr 9 09:55:31 EDT 1996Si può ripetere un comando che inizia con qualche stringa,
introducendo la parte iniziale univoca della stringa con un
!, esempio:&prompt.user; !da
date
Tue Apr 9 09:55:31 EDT 1996Quando la shell valuta la linea di comando verifica subito la
sostituzione di history prima di interpretare qualche altra cosa. Per
usare uno di questi caratteri speciali in un comando di shell è
necessario usare un escape, o effettuare un quoting, apporrendo un \ prima
del carattere, esempio \!. I caratteri di sostituzione di history sono
sintetizzati nella tabella seguente:
Comandi di sostituzione di history per la shell CComandoFunzione sostitutiva!!ripete l'ultimo comando!nripete il comando numero n!-nripete l'n-esimo comando partendo
dall'ultimo!strripete il comando che inizia con la stringa
str!?str?ripete il comando con all'interno
str!?str?%seleziona il primo argomento che ha
str all'interno!:ripete l'ultimo comando, generalmente usato con una
modifica!:nseleziona l'n-esimo argomento
dell'ultimo comando (n=0 è il nome del comando)!:n-mseleziona gli argomenti tra
l'n-esimo e
l'm-esimo argomento dell'ultimo
comando!^seleziona il primo argomento dell'ultimo comando (come
!:1)!$seleziona l'ultimo argomento dell'ultimo comando!*seleziona tutti gli argomenti del precedente comando!:n*seleziona gli argomenti
dall'n-esimo all'ultimo, incluso, del
precedente comando!:n-seleziona gli argomenti
dall'n-esimo all'ultimo, escluso, del
precedente comando^str1^str2^rimpiazza str1 con
str2 nella prima occorrenza nel
precedente comando!n:s/str1/str2/sostituisce str1 con
str2 nella prima occorrenza
nell'n-esimo comando, finendo con una
sostituzione globale g
Altre informazioni sono descritte nelle pagine
man.Cambiare la propria shellPer cambiare la propria shell si usano generalmente i comandi
&man.chsh.1; o passwd -e. Il flag di opzione, qui
, può cambiare da sistema a sistema
( su sistemi basati su BSD), quindi verificare le
proprie pagine man sul proprio sistema per un
uso corretto. Alcune volte questa caratteristica è disabilitata.
Se non si riesce a cambiare la propria shell contattare il proprio
amministratore di sistema (System Administrator).La nuova shell deve essere un path name assoluto di una valida shell
sul sistema. Le shell disponibili variano da sistema a sistema. Inoltre
il path name assoluto della shell può cambiare. Normalmente, per
la shell Bourne e la shell C sono standard e sono:/bin/sh/bin/cshAlcuni sistemi hanno anche la shell Korn standard normalmente
in:/bin/kshAltre shell, che sono poco popolari e non distribuite normalmente
dal venditore di OS, sono &man.bash.1; e &man.tcsh.1;. Queste potrebbero
essere situate in /bin o in una directory locale,
esempio /usr/local/bin o
/opt/local/bin. Se si sceglie una shell non standard
del OS, ci si deve assicurare che quella shell e tutte le shell di login
disponibili sul sistema siano elencate nel file
/etc/shells. Se questo file esiste e la propria
shell non è elencata in esso, il demone per il trasferimento di
file, &man.ftpd.8;, ti impedirà una connessione ftp su questa
macchina. Se tale file non esiste, solamente account con shell
standard possono connettersi via &man.ftp.1;.Si può sempre provare una shell prima di settarla come la
propria shell di default. Per fare questo si deve digitare il nome della
shell che si desidera utilizzare, come qualsiasi altro comando.