Introduzione a Linux

Come si presenta Linux ( Indice)

Linux e' un'implementazione di Unix distribuito con licenza della

FSF     (Free Software Foundation),

e utilizza X-Window, vario software della GNU (della FSF) e il modulo di comunicazione TCP/IP. Il kernel e' stato scritto da Linus Torvalds, Helsinki (vedi file linux.txt )

Dispone:

Configurazione base di Linux:

Per il multiuser ci sono console virtuali, normalmente ne sono definite 6.
Senza X Window si passa da una all'altra con Alt + Fn (con 1 <= n <= 6). Viene aperta una nuova sessione, di conseguenza e' richiesta nuovamente la login e la password (che puo' essere diversa da quella precedente).
Con X Window si usa Ctrl + Alt + Fn, e si torna in modo testo per una nuova sessione.
Si simula in questo modo l'esistenza di piu' terminali.

Creazione di processi

Un processo si puo' creare tramite:

Unix e' un sistema multiprocesso, quindi anche l'utente puo' avere piu' processi attivi contemporaneamente. All'interno dei processi utente si distingue 1 processo in foreground, e 0, 1 o piu' processi in background. La differenza non e', ad esempio, sui tempi dischedulazione, ma unicamente sul fatto che i processi in background non ricevono l'input da terminale keyboard, il cui uso e' riservato al processo foreground.

Si puo' lanciare un programma in background (anche piu' di uno) con l'appostito comando di shell:

disi > <comando>& 
[1] 1001 

Il carattere & indica che la shell non aspetta la fine di <comando> prima di dare un altro prompt.
Si puo' lanciare un comando in foreground e poi passarlo in background:

disi > <comando>
^z                   --> l'utente sospende il processo in fg
[4]+ Stopped         --> segnalazione del sistema
disi > bg            --> l'utente manda in background il processo
[4]+ <comando>&      --> segnalazione del sistema
disi >               --> attesa nuovo comando

Il numero fra parentesi quadre e' il numero progressivo del job in bg. Il job e' una struttura gestita dalla shell. Non si tratta di un unico processo, ma dell'insieme di processi aventi come origine il processo originaramente messo in background (ad esempio attraverso fork o pipe). Si puo' conoscere il loro stato con il comando jobs.

disi > jobs
[1] - Running comando1
[2] - Running comando2 > file1
[3] - Running comando3 < file2

Per terminare un processo si usa il comando kill #signal pid (per il processo in foreground si puo' usare il tasto ctrC, se la gestione dell'input del processo non e' raw mode). Vedere anche funzione kill in Sezione 2.
Se il #signal non e' specificato, si invia il signal "terminazione" (TERM).
kill -l consente di avere la lista dei signal predefiniti in Linux.
Invece di "pid" si puo' dare kill %1 riferendosi, ad esempio, al processo in bg [1]

disi > kill %2
[2] - Terminated  comando2 > file1

Un processo in bg perde l'uso della tastiera come standard input (ma puo' essere ridiretto). Se un job ha necessita' di emettere un output o un messaggio di errore sullo standard output, viene bloccato (coe' passa nello stato stopped). Per dare un input da tastiera o consentire l'output, bisogna riportare il processo in foreground con il comando fg. Il comando fg senza parametri si riferisce al job indicato nella lista con il carattere + (normalmente l'ultimo messo in bg). Il simbolo - indica quale sara' il successivo job "attuale".

disi > fg %1
 comando1                --> indicazione del sistema

Il job [1] passa in fg e recupera l'uso della tastiera. Riassumendo: i tasti ^Z bloccano l'esecuzione di un processo e lo mettono in background in stato stopped. Il comando bg lo attiva come background, per cui la sua esecuzione continua.

fg e bg non sono comandi (non appaiono nelle directory dei comandi), ma fanno parte della shell, come anche, ad esempio, la gestione del carattere &. In pratica, usando un'unica finestra (o senza X Window), e' possibile gestire piu' processi attivati attraverso la shell, anche se in caso di I/O da terminale la cosa diventa un po' macchinosa.
Con X Window in questo caso puo' risultare piu' comodo aprire una finestra per ogni processo, e passare in fg/bg i processi usando il mouse.

X Window ( Indice )

E' un software che funziona secondo il modello client/server distribuito. Ci sono almeno due processi coinvolti: il client, che e' quello che chiede il servizio, e il server, che e' quello che lo fornisce (servizi grafici). Non devono necessariamente risiedere sulla stessa macchina.

La comunicazione fra i due avviene tramite protocollo TCP/IP (quello di Internet) anche se risiedono sulla stessa macchina. E' quindi possibile, ad esempio, collegarsi con un altra workstation con un collegamento remoto, attivare Netscape, e chiedere al server XWindow di visualizzare la finestra Netscape remota sul nostro video. E' possibile fare cio' modificando la variabile d'ambiente DISPLAY dell'host su cui risiede il server (indica su quale display si desidera la visualizzazione) e aggiungere sul client l'host remoto su cui e' attivo il server X nell'elenco di host da cui si ricevono i dati (vedere descrizione shell bash).

ESEMPIO
Utilizzo Xserver su "arsenio" e Xclient su "krypton".
Occorre eseguire
DISPLAY=krypton.disi.unige.it:0.0 su arsenio e
xhost +arsenio su krypton.

In Linux c'e' un client particolare che usando XWindow:

Si chiama Window Manager, ne esistono di vario tipo e servono da intermediari grafici fra l'utente e XWindow. Quello standard di Linux si chiama fvwm

All'accensione, Linux si trova in modo testo e viene chiesta la login e la password. Per maggiori informazioni consultare il file linux.uso.

Si attiva XWindow con il comando startx. Viene quindi fatto partire automaticamente il server e l'unico client iniziale, il window manager, che consente di interagire in modo grafico con il sistema.

Lo sfondo e' vuoto tranne 9 rettangolini in alto a sinistra: XWindow consente di utilizzare 9 monitor virtuali, di cui uno solo e' visualizzato effettivamente. Ci si sposta di monitor cliccando su uno dei rettangolini a scelta. Su di essi viene anche visualizzato il layout delle finestre che saranno via via aperte e chiuse.


Figura 4.1

Uso dei bottoni del mouse ==> menu' relativi

  1. Sinistro. principale. Si accede cliccando a diversi menu' (sullo sfondo direttamente o sul bordo in alto delle finestre). Si possono attivare applicazioni, terminare processi, selezionare opzioni ecc. Cliccando su una finestra la si porta in primo piano.
  2. Centrale: operazioni resize, spostamenti, eliminazione sulle finestre.
  3. Destro: varie opzioni.

Per poter dare comandi Unix e' necessario attivare una shell. Si clicca con il bottone sinistro sullo sfondo e nel menu' si sceglie una delle possibili visualizzazioni della shell. Compare lo scheletro di una finestra, che si puo' trascinare con il mouse (senza premere bottoni). Quando si e' scelto il punto giusto si clicca con il bottone sinistro. Compare a questo punto una finestra grafica su cui e' stato attivita' il programma di shell preimpostato. E' possibile dare comandi come in formato testuale.

In questo menu' e'possibile selezionare anche altre utili applicazioni. ad esempio xman da' un manuale in linea di XWindow (vedi figura 4.3), mentre top da' l'elenco dei processi attivi con varie informazioni aggiornate in tempo reale (ogni pochi secondi). Accetta anche comandi interattivi (vedi manuale).


Figura 4.2

In linea di massima ogni applicazione ha la sua finestra. Provando ad esempio a dare il comando netscape &, si vedra' nuovamente comparire uno scheletro di finestra. Una volta fissata, vi sara' eseguito il programma netscape.

Una sola finestra alla volta e' attiva, cioe' riceve l'input da tastiera (confronta con esecuzione background e foreground), ma tutti i processi sono attivi, e continuano a mandare il proprio output (se ne producono) sulla finestra di attivazione (non vanno in stato stopped). La finestra attiva e' evidenziata con diverso colore.

In diversi client di XWindows (ad esempio xterm, xedit, emacs) e' possibile effettuare velocemente le operazioni taglia-cuci (solo testo) usando il mouse. Per il suo uso si rimanda ai vari manuali in linea e alle prove pratiche da terminale.


Figura 4.3

Per chiudere la sessione XWindow basta cliccare sullo sfondo e scegliere l'opzione di uscita. Si ritorna in modo testo. Succesivamente si esce dalla sessione utente con logout o crt alt del.

Non spegnere mai la corrente!!! Si rischierebbe la parziale distruzione del file system su cui si stava lavorando.

Altri comandi Unix ( Indice )

Oltre ai comandi gia' visti nella sezione 2, ricordiamo ancora i seguenti:

Editori

Sotto Linux esitono diversi editori, provare con il comando apropos editor per avere la lista.
Fra i piu' usati: vi, editore di elezione per tutti i sistemi Unix (possiede 3 ambienti operativi: comando - comandi che operano sul testo e movimenti del cursore, testo, che consente l'editing del testo, : (due punti) - comandi in linea, ad esempio per salvare il file), xedit, un semplice X editor, pico che lascia in linea l'elenco del menu' disponibile, ecc.

Messaggi

Linux, come Unix, possiede una serie di comandi utili per le attivita' di comunicazione interna e di rete. Gli utenti possono utilizzare il servizio di posta elettronica, mandare e ricevere messaggi, utilizzare il servizio di agenda in linea, trasferire file tra i nodi di una rete ed altro. Per email si possono spedire (con Unix) solo messaggi in formato testo, a causa della codifica su 7 bit usata nel protocollo standard di trasmissione.

In ogni istante si puo' controllare la presenza di email in cassetta con il comando mail. Controllare con il manuale in linea come si spedisce la posta ad altri utenti.

E' anche possibile dialogare con altri utenti attraverso il comando write nome_utente che consente di inviare un messaggio di piu' linee (terminato con end-of-file) all'utente indicato.

Tramite il comando talk nome_utente e' possibile conversare.

Il compilatore gcc

Compilatore della GNU disponibile su diverse piattaforme anche non Unix.
Alta portabilita', riferimento ANSI standard.
E' anche compilatore per C++ e Objective C.

ESEMPIO 4.1
disi > gcc hello.c                Genera l'eseguibile di hello.c su a.out.
disi > gcc -o hello hello.c       Genera l'eseguibile di hello.c su hello.

Ci sono due stadi di compilazione:

  1. Generazione del file oggetto (hello.o)
  2. Il linker (ld) genera l'eseguibile.

Le due fasi si possono separare:
disi > gcc -c hello.c              Genera hello.o
disi > gcc -o hello hello.o        Genera l'eseguibile hello a partire da hello.o.

Programmi modulari

1o modulo    .....
             void func (void)    |  modulo con dichiarazione
             main () {...}       |  main.c
             .....               |

2o modulo    ..........          |
             void func()  {...}  |  body della funzione
             ...........         |  func.c

Comando unico:
disi > gcc -o prog main.c func.c
oppure
disi > gcc -c main.c
disi > gcc -c func.c
disi > gcc -o prog main.o func.o

Si puo' compilare un solo modulo alla volta in caso di modifica.

Uso di librerie

La piu' importante e' /usr/lib/libc.a (l'estensione .a e' tipico delle librerie).
Gli header di sistema sono invece normalmente memorizzati in /usr/include

File rad.c:
#include <stdio.h>
#include <math.h>
main ()
   { printf("radice(2.0)=%lf \n", sqrt(2.0));}

disi  > gcc -o rad rad.c 
 Undefined symbol _sqrt_

L'errore e' dato perche' manca il link alla libreria matematica libm.a
Per linkare una libreria "libnome.a" si aggiunge -l nome:

disi > gcc -o rad rad.c -lm

Attenzione: non si possono raggruppare piu' opzioni insieme. Ad esempio -d -r non e' equivalente a -dr.

Comandi DOS sotto Linux ( Indice )

Sotto DOS o Windows non e' possibile accedere a Unix, mentre Unix mette a disposizione alcune utility per acceder a DOS. E' ad esempio possibile:

Al momento non e' ancora disponibile per Linux il driver per il file system FAT32.

MTOOLS

Si tratta di un insieme di comandi per la gestione di file DOS.

mattrib Cambia gli attributi dei file DOS,
mcd Cambia directory,
mcopy Copia file da e su DOS.
mdel Cancella file DOS,
mdir lista directory DOS,
mformat Crea un file system DOS su supportato gia' formattato a basso livello (con fdformat)
mmd Crea sottodirectory DOS,
mrd Rimuove sottodirectory DOS,
mread Copia file DOS su Unix a basso livello,
mren Cambia nome file DOS,
mtype Scrive su video il contenuto di un file DOS.

Con MTOOLS i dischetti sono visibili come A: come in DOS:

ESEMPIO 4.2

libra > ls alpha
  file1    prova     zorro
libra > mformat a:
libra > mmd a:/dir1
libra > mmd "a:\dir2"
libra > mcopy -t alpha/prova "a:\dir1\prova"
libra > mcd a:/dir2
libra > mcopy zorro a:/zorro.exe
libra > mdir a:
   directory for A:/DIR2
   .        <DIR>  ............
   ..       <DIR>  ............
  zorro.exe        ............

        3 file(s) ........
libra > mcd a:/
libra > mdir
   directory for A:/
   DIR1     <DIR>  ............
   DIR2     <DIR>  ............

      2 file(s) ............

DOS inserisce alla fine di ogni file ASCII i caratteri <CR><LF>, mentre Unix usa solo <LF> (Line Feed). Per poter trasferire correttamente i file da DOS a Unix si usa l'opzione -t.

Per maggiori informazioni sull'uso di questi comandi (e degli altri precedenti) consultare, come al solito, il manuale in linea con il comando man.

Make ( Indice )

Se si deve compilare un grosso programma modulare, e' utile avere una utility che alleggerisca il compito. Ad esempio, con il linguaggio C, e' possibile dividere un programma in moduli funzionali, in funzioni di libreria, e in file header, contenenti definizioni di tipi e variabili. Le relazioni fra moduli e header possono essere anche molto complesse, e la modifica in uno di essi richiede normalmente la ricompilazione di una parte dei moduli.

Make e' una utility Unix che fornisce questo aiuto, consentendo di definire le relazioni fra moduli e header, definire le opzioni di compilazione, effettuare operazioni di cancellazione dei file non piu' necessari e cosi' via.

Le informazioni sono scritte in un file (per default il nome e' Makefile) con un apposito linguaggio. Sono definiti dei target (almeno uno), cioe' degli obiettivi, richiamabili dal programma. Ad esempio ci puo' essere il target compila, cancella, installa ecc.

Consideriamo un programma C formato da 2 moduli: main.c e proc.c.
Definiamo 2 target principali:

  1. formare l'eseguibile, dopo aver fatto una compilazione separata dei 2 moduli.
    Il nome del target e' EXE
  2. cancellare gli object. Il nome e' CLEAN
ESEMPIO 4.4
# Makefile 
EXE:     main.o  proc.o
         gcc  -o  prog  main.o  proc.o
CLEAN:   rm  -f  proc.o  main.o
main.o:  main.c
proc.o:  proc.c
# fine Makefile

Attenzione: la seconda colonna inizia con dei <tab> e non con dei blank.

Un target si indica con il nome (da colonna 1) seguito da ":" e dall'elenco delle dipendenze. Ad esempio per eseguire EXE e' necessario avere i due file main.o e proc.o.

Una volta definite le dipendenze, si dice come si fa ad ottenere il target. Nel caso EXE si devono compilare insieme i due object.

I due termini main.o e proc.o nel target EXE sono pero' ancora indefiniti, cioe' sono a loro volta dei target. Si definiscono allora i sottotarget main.o e proc.o con le loro dipendenze. Il comando gcc -c main.c non e' specificato: si tratta di un comanmdo elementare che make esegue senza la necessita' di specificarlo. In realta' non e' veramente necessario neanche specificare i sottotarget main.o e proc.o, se si ottengono semplicemente per compilazione dei file C con lo stesso nome.

E' possibile anche definire delle macro di sostituzione.

Vediamo un altro esempio con due moduli (main.c e proc.c) e un header incluso in main.c. I moduli codice sono nella sottodirectory src, gli header in include. La directory principale e' /usr/users/gianuzzi. Il file eseguibile va memorizzato sotto /bin.

ESEMPIO 4.5
# definizione delle directory
u = /usr/users/gianuzzi
i = $u/include
e = /bin
s = $u/src
# definizione flag di compilazione
FLAGS = -i

PROG:    main.o  proc.o
         gcc  $(FLAGS) -o  $e/prog  main.o  proc.o
main.o:  $s/main.c
main.o:  $i/main.h
proc.c:  $s/proc.c
CLEAN:   rm  main.o  proc.o

Il carattere $ indica che il carattere che segue e' una macro da espandere. Se l'identificatore della macro e' piu' lungo di 1 carattere, si racchiude fra parentesi tonde.

Un po' di sintassi:

   make  [flags]  [macro def.]  [target]

L'argomento opzionale [macro def.] sostituisce le definizioni nel Makefile.

flags:
-s  silent mode
-n  no-execute mode (solo lista delle operazioni 
    che sarebbero effettuate).
-p  print di macro e target
-d  debug mode
-f  l'argomento successivo e' il nome del makefile 
    (per usare un nome diverso ad Makefile).

Nell'esempio 4.4, con il comando make EXE viene visualizzato (la prima volta):

   gcc   -c   main.c   -o   main.o
   gcc   -c   proc.c   -o   proc.o
   gcc   -o   prog   main.o   proc.o

ed e' creato l'eseguibile prog.
viene poi modificato il file main.c. Al successivo make EXE:

   gcc   -c   main.c   -o   main.o
   gcc   -o   prog   main.o   proc.o

make non ricompila proc.c perche' non e' stato modificato (viene controllato se il tempo dell'ultima modifica a proc.c e' precedente o successivo a quello di creazione di prog).

Un esempio di makefile lo trovate su minix_makefile.html


La Shell bash ( Indice )

La shell e' un programma che interpreta i comandi dell'utente. I comandi possono essere dati da terminale, oppure contenuti in file testo (detto script), che viene letto ed eseguito dalla shell. Una shell puo' essere:

La shell di login viene attivata automaticamente all'atto di login (vedi sezione 3). Interpreta prima di tutto uno script uguale per tutti gli utenti e scritto dal sistemista: /etc/profile. Successivamente esegue uno script definito dall'utente, nella propria home directory. Il nome di questo script varia a seconda del tipo di shell.

Per la bash, esegue solo il primo script fra:
~/.bash_profile, ~/.bash_login, ~/.profile
con l'operazione source (spiegata dopo).

L'utente puo' quindi "personalizzare" il suo ambiente di lavoro usando lo script di login. Inoltre, anche alla sua attivazione la shell esegue automaticamente lo script ~/.bashrc , sempre con operazione source.

All'uscita della sessione viene eseguito lo script ~/.bash_logout.

Se uno o piu' di questi script non esistono, non viene dato nessun errore.

~    indica la home directory, e puo' anche essere scritto come $HOME.

Uno script e' dunque una lista di comandi Unix o di shell. Se non specificato altrimenti si suppone che sia la shell sh (che in Linux e' identificata con bash) ad interpretarli. Se si vuole utilizzare un altra shell, si indica sulla prima linea. Per vedere alcune caratteristiche delle diverse shell, leggere shell.txt.

  #! /bin/tcsh
  ......

il carattere "#" in prima colonna, senza "!" dopo indica una riga di commento.

Negli script non si eseguono solo comandi, si possono anche definire delle variabili d'ambiente che possono poi essere riferite nei comandi, premettendo il carattere "$".

Ci sono almeno due modi per eseguire uno script:

  1. dandone semplicemente il nome, con eventuali argomenti. In questo caso viene attivata una nuova shell (sh, tcsh, ksh o altro, come indicato nella prima linea dello script) che esegue i comandi dello script e poi termina (vedi lo schema di esecuzione comandi della sezione 3). Lo script deve essere marcato "eseguibile" attraverso il comando chmod .
  2. attraverso il comando source (abbreviato anche con il carattere ".") seguito dal nome dello script. In questo caso i comandi sono eseguiti all'interno della shell corrente.

Parlando di comandi ci sono diverse possibilita':

Cenni di Grammatica della shell bash

Un pipeline e' un comando o una sequenza di comandi separati dal carattere "|". In questo caso l'output di un comando e' preso come input dal successivo. Vedere esempio in pipe di comandi .

Una lista e' una sequenza di pipeline separati da un operatore fra

 e terminata da uno fra   ;  &  <newline>.

Sia i pipeline che le liste restituiscono un valore di ritorno, =0 oppure =1 in dipendenza dell'operazione effettuata.

E' possibile definire dei compound command come: (i parametri fra [ ] sono opzionali)

Attenzione ai blank, eliminarli puo' causare errore.

E' possibile assegnare delle variabili di tipo stringa di caratteri, poi riferibili nella stessa shell. Una variabile e' assegnata con lo statement
name=[ value ]
Se value e' assente il valore e' la stringa nulla. L'assegnazione e' valida solo nella shell in cui e' eseguita, ma puo' essere esportata nelle shell di livello inferiore con il comando di shell export.
Il comando export da solo lista le variabili esportate, con i valori loro assegnati.
Non mettere blank prima o dopo il carattere =.

ESEMPIO
  export  A=100
  B=1000
  export B

Il nome e il valore di alcune variabili sono predefinite dalla shell, e non possono essere modificate direttamente, altre sono definite come nome, ma non assegnate (sono utilizzate implicitamente da alcuni comandi):

Il comando cd, ad esempio, e' interpretato dalla shell, e riassegna la variabile PWD, utilizzata dal comando pwd.

Quando si da' un comando (o si richiede l'esecuzione di un processo) la shell ricerca il file eseguibile nelle directory indicate nella variabile PATH. Si indicano quindi in sequenza i path assoluti delle directory, separate dal carattere :. Il carattere "." indica la WD generica, cioe' quella in cui ci si trova al momento di dare un comando, non la WD in cui e' eseguito lo script "star". Si consiglia di metterla sempre per ultima.

Alias

Si possono definire nomi diversi per i comandi.

ESEMPIO
   alias   del='rm  -i'
   alias   dir='ls  -l'

Per l'uso del carattere ', vedere piu' avanti quoting.

Per conoscere la lista degli alias si usa il comando alias senza argomenti.
alias nome da' l'alias definito per quel nome.
Il comando set stampa le variabili che sono state definite.
Il valore di una variabile si referenzia facendola precedere dal carattere $.

ESEMPIO

Nell'esempio sopra si aggiunge (in coda) la directory corrente (i due punti servono da separazione) e la directory $HOME/bin, come directory in cui effettuare la ricerca degli eseguibili. Viene poi stampato il valore di PATH. Si copiano i file main.c e main.h nella directory "./tmp". Se i file non sono presenti nelle directory indicate, lo script termina (exit). Si passa nella sottodirectory "/tmp". Si compone il file tar "main.tar". Si cancellano i file copiati nella WD e si torna nella home directory.

ESEMPIO

Provare ad eseguire i comandi sexp ; sexe (rendere eseguibili gli script!).
Provare poi ad eseguire source sexp ; sexe .

ESEMPIO
ESEMPIO
ESEMPIO

Provare a lanciare la shell s5 come comando "s5" e come "source s5".

Comandi builtin

Questa e' solo una lista limitata e alcuni comandi sono gia' stati visti prima o nelle sezioni precedenti. Le parentesi quadre indicano parametri opzionali, tranne nel caso del comando test abbreviato.

source nome_script argomenti
alias [ name [ = value ] ... ]
bg [ jobspec ]
fg [ jobspec ]
jobs [ -lnp ] [ jobspec .... ]
cd [ dir ]
kill [ -s sigspec | -sigspec ] [ pid | jobspec ] ...

echo [ -neE ] [ arg ... ]      
              Output argomenti separati da blank. Ritorna 0.
exec [ [ - ] command [ arguments ] ]
              Esegue il comando nella shell corrente.
              Senza command puo' avere una redirezione dell'I/O.
exit [ n ]
              Exit dallashell con status = n.
export [ -nf ] [ name [ = word ] ] ....
help [ pattern ]
pwd
read [ -r ] [ name ... ]

             Legge una linea dallo standard input: la prima word e' assegnata al primo name e cosi' via.
set [ ... ] [ arg ... ]
test expr
oppure
[ expr ]
             Le parentesi quadre sono in questo caso obbligatorie, come pure il blank di separazione.
             Ritorna 0 o 1 in dipendenza della valutazione di expr.
umask [ -s ] [ mode ]
unalias [ name ... ]
             Rimuove name dalla lista degli alias definiti.
unset [ -fv ] [ name ... ]
              Rimuove la variabile name dall'insieme delle variabili definite.
wait [ n ]
              Aspetta la terminazione del processo o job indicato.

Il comando test e' molto usato, specialmente nella sua forma abbreviata [ expr ]. Si possono ad esempio verificare proprieta' dei file, o uguaglianza di stringhe (non valori numerici).

Alcuni esempi:

test -d file         vero se file esiste ed e' una directory.
test -f file         vero se il file esiste ed e' un file di dati.
test -e file         vero se il file esiste.
test -L file        vero se il file esiste es e' link simbolico.
test -r file         vero se il file esiste ed e' leggibile.
test -x file         vero se il file esiste ed e' eseguibile.
test stringa1 = stringa2       vero se uguali.
test stringa1 != stringa2      vero se diversi.

Il comando   test expr   puo' anche essere scritto come:   [  expre  ]

ESEMPIO

#! /bin/bash 
# script di login 
# attenzione ai blank nella prossima linea 
if [ "$LOGNAME" = "root" ]; then 
     echo " Welcome dear $LOGNAME" 
     if [ -f $HOME/hello ]; 
         then echo $HOME/hello 
     fi 
fi 

ESEMPIO

#! /bin/sh 
# script sbh 
if [ "$SHELL" = "/bin/bash" ]; then 
    PS1="sono la shell bash > " 
fi 
# fine 

Eseguire lo script sbh come "source sbh". Attenzione ai blank obbligatori.

ESEMPIO

#! /bin/sh 
echo -n "stringa ? " # non va a capo 
read VAR 
case $VAR in 
      "ALPHA" | "BETA" | "GAMMA" ) 
           echo maiuscolo ;; 
      "alpha" | "beta" | "gamma" ) 
            echo minuscolo ;; 
      * ) 
            echo altro ;; 
esac 

Parametri posizionali

Sono i parametri della chiamata ad uno script.
Si identificano con il carattere $ seguito dall'indice della posizione. Se si usano numeri di 2 cifre, si racchiudono fra parentesi graffe.

ESEMPIO
   nome_script   alfa    10 
      $0          $1     $2 

Parametri speciali:

  • $0     nome dello script.
  • $@   collezione di tutti i parametri (a partire da $1). Quando si usa all'interno dei doppi apici (vedi quoting piu' avanti) rappresenta l'insieme dei parametri come word separate: "$1" "$2" ... "$n".
  • $*    stringa ottenuta concatenando tutti i parametri in un'unica stringa. I parametri sono separati fra loro dal primo carattere della variabile IFS (normalmente lo spazio). Quindi "$*" indica "$1 $2 $3 .. $n".
  • $#    numero di parametri presenti.
  • $$    processs id della shell.
  • $-    flag opzionali.
  • ESEMPIO

    Lo script completo lo trovate nel file minix_mkboot.html .

    Prompting

    Il primary prompt PS1 puo' essere modificato run time.
    Ci sono per questo dei caratteri speciali:

       \t   tempo corrente
       \d   data corrente
       \w   current working directory
       \u   username
       \h   hostname
       \#   command number
       \!   history number
       ecc.
    
    ESEMPIO
       PS1='[\!]\h:\u > '
    

    Sul file shell.html si trovano altri esempi di shell.

    Espansioni

    Ci sono diversi tipi di espansioni che vengono effettuate dalla shell prima di attivare i comandi richiesti:

    ESEMPIO
       rm  `find . -name "*.obj"`

    Quoting

    Ci sono altri tipi di apici oltre al ` usato per il command substitution:

    ESEMPIO
      #! /bin/bash
      echo "numero argomenti = $#"
      for i in $*
      do
         echo  "argomento $i"
      done
    
    ESEMPIO
      #! /bin/bash
      # script s1
      VAR=`ls`            # lista corta di tutti 
      echo  VAR=$VAR      # i file della WD
      for i in $VAR; do
        ls -ld $i; done   # lista lunga
    

    provare ad eseguire s1 e source s1.

    File gestiti dal superuser e amministratore ( Indice )

    Quanto segue si riferisce ad un insieme di file che sono gestiti dal sistema, dal superuser, o costituiscono log (cioe' tracce storiche di eventi accaduti nel sistema). Non sono interamente standard, quindi potrebbe esserci qualche differenza fra diversi Unix, ma la "filosofia" di uso e' sempre la stessa (vedere http://www.pathname.com/fhs).

    Una directory importante e' /etc/, che contiene file e sottodirectory che descrivono la configurazione del sistema. Nel seguito ne sono descritte alcune.

    Informazioni sui processi

    /proc/
    Nella sezione 3 abbiamo visto che il kernel gestisce la Process Table in cui sono mantenute varie informazioni sui processi attivi. Alcune di queste informazioni sono accessibili attraverso il file /proc/ (gestito comunque diversamente dai vari sistmi Unix). Si tratta in realta' di una directory virtuale, cui non corrisponde nessuno spazio disco (vedere come e' listata nel comando df). Per ogni processo contiene un entry, file o altra sottodirectory.

    Definizione utenti

    /etc/passwd
    In questo file ogni riga rappresenta un utente. Le informazioni sono separate dal carattere ":" e sono in sequenza:

    1. nome login
    2. password criptata (non sempre visibile)
    3. UID utente
    4. GID utente (gruppo principale di appartenenza)
    5. informazioni generali, tipo nome e cognome
    6. home directory dell'utente
    7. shell da lanciare
    ESEMPIO
    root:F.qR9xt:0:0:root:/root:/root:/bin/bash
    bin:*:1:1:bin:/bin
    gianuzzi:AV143b.xq:113:12:Vittoria Gianuzzi:/home/gianuzzi:/bin/bash
    

    Il carattere "*" indica che quell'utente non puo' collegarsi. Si tratta cioe' di un raggruppamento di comodo di file con proprieta' particolari. Non sempre le password criptate sono visibili, per motivi di sicurezza possono essre mantenute nel file /etc/shadow.

    Il comando per aggiungere un utente e' adduser, eseguibile solo dal superuser. E' un comando interattivo, in cui vengono chieste una alla volta le varie informazioni. Viene cosi' inserita una linea in passwd. I valori di default sono definiti in /etc/skel. Non sempre adduser e' fornito (ad esempio non c'e' in MINIX). In questo caso si puo' semplicemente aggiungere una linea (senza password) nel file. La password la mette sucessivamente l'utente stesso.

    Per cancellare un utente si cancella la riga con l'editore. Se c'e' anche un sistema di sicurezza sulla manipolazione del file passwd, occorre dare gli opportuni comandi. Inoltre, si rimuove la sua home directory e lo si elimina anche dal file /etc/group (vedi sotto). Ci sono anche altre directory in cui si possono trovare file di un utente. Ad esempio /var/mail usata per la posta.

    Il superuser non puo' conoscere la password dell'utente, ma puo' accedere comunque a tutti i suoi file, e cambiare la sua linea in passwd.

    Il file /etc/passwd puo' anche essere modificato dall'utente con i comandi passwd per cambiare la password (viene chiesta anche quella vecchia). Nel file /etc/passwd c'e' la lista di tutte le shell disponibili. Con la funzione chsh l'utente puo' modificare la propria shell di login, purche' quella nuova sia inclusa nell'elenco. Per la modifica viene chiesta la password.

    Definizione di gruppi di utente

    /etc/group
    Ogni gruppo e' memorizzato su una riga di questo file. Le informazioni sono:

    1. nome gruppo
    2. password per acquisire i diritti del gruppo (spesso non usata)
    3. GID (numero del gruppo)
    4. login degli utenti appartenenti al gruppo, separati dalla virgola. Un utente puo' appartenere a piu' gruppi.
    ESEMPIO
       root::0:root
       bin::1:root,bin
       users::100:gianuzzi,pinco
       sys::13:pippo,gianuzzi
    

    Definizioni di mounting point

    /etc/fstab
    contiene per ogni FS montato, le indicazioni collegate. E' scritto e aggiornato, se il caso, dal sistemista.

    ESEMPIO
    krypton > more fstab
    /dev/rz6a       /       ufs rw 1 1
    /proc   /proc   procfs rw 0 0
    /dev/rz6g       /usr    ufs rw 1 2
    /dev/rz6b       swap1   ufs sw 0 2
    /dev/rz6h       /usr/local ufs rw 1 2
    /dev/rz3c       /usr/users ufs rw 1 2
    

    Messaggi e log di sistema

    /var/adm/...
    Demoni e altri programmi di sistema scrivono messaggi d'errore o altre informazioni su file nella directory /var/adm/ (e quindi crescono nel tempo). Ad esempio:

  • /var/adm/messagess Messagi dalla console di sistema (per Xwindows c'e' Xconsole).
  • /var/adm/syslog Messaggi scritti da programmi che utilizzano il servizio syslogd.
  • Utilizzo di stampanti

    Si utilizza il sistema di spooling.

    1. Il comando lpr copia il file da stampare in un'area apposita (spool), cioe' una directory relativa alla particolare stampante usata. Altri comandi utili sono lpq per avere informazioni sulla coda di stampa di una particolare stampante, e lprm che consente di eliminare un file dalla coda di stampa, se se no hanno i privilegi.
    2. Il demone lpd verifica in continuazione l'area di spool. Quando c'e' un file nuovo lo invia sul device di stampa. Finita la stampa, cancella il file. L'ordine di stampa e' FIFO.

    Oganizzazione file:

    1. /var/spool/       Directory con sottodirectory di spooling per ogni stampante.
    2. /etc/printcap    File contenente la descrizione delle proprieta' di ciascuna stampante disponibile.
    3. /usr/bin/lpr     Programma di stampa.
    4. /usr/bin/lpd     Demone di stampa.
    5. /usr/bin/lpc     Programma di controllo dello stato della stampante.

    Una singola stampante puo' avere piu' nomi, e un driver diverso collegato ad ogni nome. Per scegliere il nome della stampante si usa sempre l'opzione -P <nome_stampante>.
    Ad esempio lpr -Plw162 pippo.txt stampa il file pippo.txt sulla stampante di nome lw162. Se non si indica nessun nome di stampante, ci si riferisce a quella di default definita del sistemista.