Comments
Description
Transcript
Nessun titolo diapositiva
1* 2* 3* 4* Questo capitolo tratta di sistemi di numerazione a base diversa da quella decimale alla quale siamo abituati. Impareremo i numeri binari vale a dire quelli con base 2, i numeri ottali, cioe’ quelli con base 8, ed i numeri esadecimali, cioe’ quelli con base 16. Vedremo che questi sistemi di numerazione sono piu’ utili di quello decimale per descivere il contenuto di una qualunque cella di memoria o registro del computer. Questo poiche’ questi ultimi sono sempre composti o da circuiti elettronici o da dispositivi magnetici o da dispositivi ottici che possono assumere solo 2 possibili stati (ON ed OFF; magnetizzazione YES or NO; superficie riflettente o non riflettente etc.) Cosi’ il sistema binario, cioe’ quello che usa solo 2 cifre per descrivere i numeri, diventa il modo piu’ naturale da usare con un computer, per contare i numeri. L’utilita’ della numerazione ottale ed esadecimale discende in sostanza dal fatto che sono sistemi di numerazione piu’ sintetici (uno stesso numero in ottale od esadecimale e’ molto piu’ corto del corrispondente binario) che si possono molto facilmente e direttamente trasformare nel corrispondente numero binario. 5* 7.1 Numerazioni con basi 2, 8, 16 Base 10 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ho finito le cifre, metto 1 in una colonna piu’ a sinistra e nella colonna piu’ a destra riparto da 0 La base di un sistema di numerazione e’ il numero di simboli (cifre) usati per descrivere i numeri. Il sistema binario usa solo due cifre : 0 ed 1 ; quello ottale usa otto cifre : 0, 1, 2, 3, 4, 5, 6, 7 ; quello decimale, come e’ noto, ne usa dieci , dallo 0 al 9 ; infine quello esadecimale ne usa sedici : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. In tutti i sistemi di numerazione, analogamente al caso della numerazione decimale, si usa la notazione posizionale Numeri decimali, notazione posizionale : 173.2 = 1x102 + 7x101 + 3x100 + 2x10-1 ho finito le cifre, metto 2 nella colonna piu’ a sinistra e nella colonna piu’ a destra riparto da 0 6* 7.1 Numerazioni con basi 2, 8, 16 Base 10 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Base 2 0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 10000 10001 10010 10011 10100 ho finito le cifre, metto 1 in una colonna piu’ a sinistra e nella colonna piu’ a destra riparto da 0 ho finito le cifre, metto 1 in una colonna piu’ a sinistra e nelle colonne piu’ a destra riparto da 0, etc. Numeri binari traduzione in numero decimale : 1011.1(2) 1x23 + 0x22 + 1x21 + 1x20 + 1x2-1 = 11.5(10) 7* 7.1 Numerazioni con basi 2, 8, 16 Base 10 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Base 2 Base 8 0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 10000 10001 10010 10011 10100 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 Numeri ottali traduzione in numero decimale : 172.6(8) 1 x 82 + 7 x 81 + 2 x 80 + 6 x 8-1 = 122.75 (10) ho finito le cifre, metto 1 in una colonna piu’ a sinistra e nella colonna piu’ a destra riparto da 0 ho finito le cifre, metto 1 in una colonna piu’ a sinistra e nelle colonne piu’ a destra riparto da 0, etc. 8* 7.1 Numerazioni con basi 2, 8, 16 Base 10 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Base 2 Base 8 0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 10000 10001 10010 10011 10100 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 Base 16 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 Numeri esadecimali traduzione in numero decimale : 1B2.6(16) 1 x 162 +11 x 161+2 x 160+6x16-1 = 434.375 (10) ho finito le cifre, metto 1 in una colonna piu’ a sinistra e nelle colonne piu’ a destra riparto da 0, etc. 9* 7.2 Come passare da un numero decimale al corrispondente binario, ottale, esadecimale Direttamente con degli esempi, facciamo vedere coma passare da un numero decimale al corrispondente binario, ottale, esadecimale. Esempio : passare da 29.2 (decimale) al corrispettivo binario 1 Si considera prima la parte intera, eseguendo divisioni successive per 2 fino a quando il risultato fa 0. Le cifre ottenute sono la parte intera del numero binario corrispondente a quello decimale. 29 : 2 = 14 1 Il resto della divisione diventa una cifra binaria 14 : 2 = 7 0 7 :2= 3 1 3 :2= 1 1 1:2= 0 1 ultimo resto : cifra piu’ significativa 1 1 primo resto : cifra meno significativa 1 0 1 il risultato della divisione e’ 0, il procedimento e’ finito 10* 2 Si considera poi la parte decimale, eseguendo moltiplicazioni successive per 2 fino a quando il risultato fa 0 oppure finche’ si e’ raggiunta la precisione desiderata. Le cifre ottenute sono la parte a destra del punto. 0.2 x 2 = 0.4 + 0 La parte intera del risultato diventa una cifra binaria. La parte decimale viene ancora moltiplicata per la base 2 0.4 x2 = 0.8 + 0 . 0 0 0.8 x 2 = 0.6 + 1 1 1 primo parte intera : cifra decimale piu’ significativa 0.6 x 2 = 0.2 + 1 cifra decimale meno significativa La parte decimale del risultato della moltiplicazione non e’ 0, ma la precisione raggiunta mi soddisfa. Termino il procedimento. Risultato finale : 29.2 decimale 11101.0011 binario 11* Esempio : passare da 139 decimale al corrispettivo ottale E’ gia’ un numero intero, cosi’ dovro’ solo eseguire il passaggio 1 dell’esempio precedente. Ora eseguo divisioni successive per 8 fino a quando il risultato fa 0. Le cifre ottenute sono il numero ottale corrispondente a quello decimale. 139 : 8 = 17 3 17 : 8 = 2 1 2 :8= 0 2 il risultato della divisione e’ 0, il procedimento e’ finito ultimo resto : cifra piu’ significativa 2 1 3 primo resto : cifra meno significativa Risultato finale : 139 decimale 213 ottale 12* Esempio : passare da 139 decimale al corrispettivo esadecimale E’ gia’ un numero intero, cosi’ dovro’ solo eseguire il passaggio 1 dell’esempio precedente. Ora eseguo divisioni successive per 16 fino a quando il risultato fa 0. Le cifre ottenute sono il numero esadecimale corrispondente a quello decimale. 139 : 16 = 8 11 8 : 16= 0 8 il risultato della divisione e’ 0, il procedimento e’ finito ultimo resto : cifra piu’ significativa 8 B primo resto : cifra meno significativa Risultato finale : 139 decimale 8B esadecimale 13* 7.3 Come passare da un numero ottale od esadecimale al corrispondente binario e viceversa Passare da un numero ottale od esadecimale al corrispondente binario e’ molto facile e viene illustra to negli esempi che seguono. Anche il viceversa non comporta calcoli particolarmente difficili. Capiamo cosi’ anche perche’ i numeri ottali od esadecimale vengano preferiti, quando possibile, ai binari : sono molto piu’ sintetici di quest’ultimi (necessitano di minori numero di digits per descrivere lo stesso numero) e si possono all’occorrenza trasformare in binari molto facilmente. 14* Esempio : passare da 172 ottale al corrispettivo binario per ogni cifra ottale scrivo i corrispondenti 3 digits binari 1728 001 111 010 = 11110102 Risultato finale : 172 ottale 1111010 binario il numero binario corrispondente si ottiene accostando nell’ordine i digits binari Esempio : passare da 1010001 binario al corrispettivo ottale Inizio suddividendo, PARTENDO DA DESTRA, il numero binario di 3 cifre in 3 cifre. Ad ogni terzina sostituisco la corrispondente cifra ottale. 1 010 001 2 001 001 010 001 1 2 1 faccio l’operazione inversa a quella di prima. Sostituisco ai 3 digits binari il corrispondente numero ottale Risultato finale : 1010001 binario 121 ottale 15* Esempio : passare da 1D8 esadecimale al corrispettivo binario 1D816 per ogni cifra esadeciamle scrivo i corrispondenti 4 digits binari 0001 1101 1000 = 1110110002 Risultato finale : 1D8 ottale 111011000 binario il numero binario corrispondente si ottiene accostando nell’ordine i digits binari Esempio : passare da 10111100110 binario al corrispettivo esadecimale Inizio suddividendo, PARTENDO DA DESTRA, il numero binario di 4 cifre in 4 cifre. Ad ogni quaterna sostituisco la corrispondente cifra esadecimale. 0101 101 1110 0110 2 0101 1110 0110 5 E 6 faccio l’operazione inversa a quella di prima. Sostituisco ai 4 digits binari il corrispondente numero esadecimale Risultato finale : 10111100110 binario 5E6 esadecimale 16* 7.4 Somma tra numeri binari, ottali, esadecimali Valgono la stesse regole di somma e di riporto valide pei numeri decimali. Ancora una volta chiariamo queste regole con degli esempi. Esempio : eseguire la somma (decimale) 29 + 233 coi corrispondenti numeri binari, ottali, esadecimali Base 10 riporti 1 29 + 233 = 2 62 Base 2 1 1 11 1 1 11101 + 11101001 = 1 00 00 0 1 1 0 Base 8 1 35 + 351 = 4 06 Base 16 11 1D + E9 = 1 06 17* 7.5 Moltiplicazione tra numeri binari, ottali, esadecimali Valgono la stesse regole di moltiplicazioni parziali valide pei numeri decimali. Ancora una volta chiariamo queste regole con degli esempi. Esempio : eseguire la moltiplicazione (decimale) 20 * 21 coi corrispondenti numeri binari, ottali, esadecimali Base 10 20 x 21 = 20 40 420 Base 2 10100 x 10101 = 10100 00000 10100 00000 10100 Base 8 Base 16 24 x 25 = 144 50 14 x 15 = 64 14 644 1A4 110100100 18* Computer : insieme di circuiti elettronici + sistemi elettromeccanici (tastiera, stampante, monitors). Puo’ eseguire calcoli ed operazioni basandosi su istruzioni che vengono messe nella memoria allo scopo di manipolare dati (input) e produrre risultati (output) Sequenza di istruzioni = programma Un computer e’ formato (almeno) dalle seguenti parti essenziali 1) Memoria : insieme di dispositivi magnetici (nastri, dischi) ottici (dischi laser) o di circuiti elettronici (ad es. la RAM = random access memory) dove vengono conservate le informazioni (istruzioni dei programmi, dati di input, dati di output). La memoria a rapido accesso di solito e’ di dimensioni non molto grandi ed e’ di tipo transitorio. Vi accede di solito la CPU durante il processo di calcolo. La memoria di massa invece e’ di tipo permanente, e serve per immagazzinare grandi quantita’ di dati, e vi si accede in modo piu’ lento. Ciascun insieme di dati e’ chiamato file. 19* 2) CPU (central processor unit) costituito da (almeno) due parti : una parte che acquisisce le istruzioni del programma e le decodifica, una parte aritmetica che fa i calcoli. 3) Dispositivo di input : tastiera del computer, lettore di nastri, lettore di dischi etc. Serve per dare comandi e fornire dati 4) Dispositivo di output : video, stampante etc. Dispositivi per raccogliere i risultati. Parte centrale Memoria RAM periferica periferica ingresso CPU uscita Memoria di massa periferica 20* La parte centrale (CPU, RAM) e’ costituita da circuiti elettronci veloci, al giorno d’oggi i clock piu’ veloci raggiungono 3.0 GHz. La memoria di massa ed i dispositivi di input/output possono essere costituiti anche da parti meccaniche (tastiera, dischi) e l’accesso e’ piu’ lento. Di solito il passaggio dei dati tra unita’ lente ed unita’ veloci vengono gestiti in modo automatico senza usare la CPU. Le unita’ piu’ lente in linea di principio potrebbero essere staccate senza pregiudicare il funzionamento della parte centrale e per questo vengono dette unita’ periferiche. Le memorie e la CPU sono composte da parole (da registri nel caso della CPU). Ogni parola e’ composta da bytes ed ogni byte e’ composto da 8 bits. Un bit e’ un oggetto (ad es. un microcircuito elettronico bistabile; del materiale magnetizzabile di un disco o di un nastro etc.) che puo’ trovarsi in DUE stati i quali simboleggiano la cifra 0 e la cifra 1 rispettivamente. In tal modo ad ogni parola o registro (che spesso al giorno d’oggi e’ composta da 8 bytes, cioe’ 64 bits) e’ associabile un numero binario. Tutti i dati (numeri, lettere e caratteri, istruzioni di un programma) vengono codificati in numeri binari. 21* Il numero 19(10) viene messo in una parola di 32 bits col suo equivalente binario : 00000000000000000000000000010011 La parola Roma viene immagazzinata usando per ciascuna lettera 1 byte e codificando con il codice ASCII R 01010010 ; o 01101111 ; m 01101101 ; a 01100001 I bytes vengono ‘accostati’ l’uno all’altro formando una parola di 32 bits in totale. Nell’accostarli il carattere piu’ a sinistra viene messo dalla parte dei bits meno significativi (cioe’ quelli per cosi’ dire ‘piu’ a destra’) compiendo cosi’ in un certo senso una ‘inversione’. Quindi alla fine Roma viene immagazzinata in 32 bits come segue : 01100001011011010110111101010010 Il codice ASCII originariamente era uno standard USA; oggi e’ diventato internazionale. La codificazione dei caratteri e’ ‘machine independent’ e quindi permette di trasportare facilmente qualsiasi file di informazione da un computer ad un altro. 22* Tabella ASCII X3.4-1977 http://www.cs.utk.edu/~shuford/terminal/ascii_table.txt 23* Istruzioni e linguaggi dei computers Il computer per eseguire il programma obbedisce ad una sequenza di istruzioni. Le istruzioni, al livello piu’ basso, vengono scritte in ciascuna parola del file contenente il programma, in CODICE MACCHINA, che dipende dal particolare computer. Ad esempio, una parola del tipo 011000000000011001010000 potrebbe significare : prendi il contenuto della locazione di memoria chiamata B e copialo nel registro n. 3 della CPU. Storicamente il codice macchina fu il primo linguaggio sviluppato. In seguito, per motivi di praticita’ fu introdotto il linguaggio assemblatore (ASSEMBLER) che usa forme mnemoniche piu’ facili da ricordarsi. Ad esempio, l’istruzione precedente potrebbe avere il suo equivalente assembler in LDX 3 B dove LDX sta per load (carica). Anche l’assembler dipende dal particolare computer, ed una istruzione assembler corrisponde ad una operazione della CPU. 24* Successivamente all’assembler furono inventati i linguaggi ad alto livello che hanno una sintassi indipendente dal particolare computer e permette al programmatore di scrivere istruzioni senza dover conoscere alcunche’ del linguaggio macchina. Il programmatore dovra’ dunque scrivere un file ASCII in cui sono contenute le istruzioni del programma. Ciascun computer d’altra parte, dovra’ essere dotato di un COMPILATORE cioe’ di un programma in grado di trasformare automaticamente qualunque file ASCII di istruzioni del linguaggio ad alto livello in un file contenete l’equivalente in codice macchina. Le istruzioni del linguaggio ad alto livello avranno una sintassi facile da ricordare ed usare, con comandi che corrispondono a piu’ comandi di codice macchina. Sara’ cosi’ possibile usare un programma su qualunque macchina, a patto che abbia il compilatore adatto, e verra’ facilitato lo sviluppo di programmi (software) anche complessi da parte di piu’ persone. Il FORTRAN 77 (ForTran = Formula Translation) e’ un linguaggio ad alto livello. Altri esempi sono : COBOL, PASCAL, BASIC, C, C++. Il Fortran 77 venne codificato nel 1980. E’ specialmente adatto per fare calcoli numerici per progetti, simulazioni, etc. Per questo linguaggio esistono inoltre molte librerie, cioe’ raccolte di programmi gia’ scritti nel corso degli anni che semplificano ed alleviano la mole di lavoro al programmatore. 25* Multitasking e time sharing I computers odierni in generale sfruttano il principio della multiprogrammazione (multitasking) che si basa sul fatto che il tempo con cui una CPU esegue calcoli matematici o logici e’ molto inferiore al tempo con cui il computer trasferisce i dati dall’input alla CPU o dalla CPU all’output. Si risparmia tempo complessivamente se si eseguono piu’ programmi in una volta e mentre i dati di un programma vengono trasferiti (in maniera automatica che non coinvolge la CPU) la CPU esegue calcoli per un altro programma. Un altro principio oggi seguito e’ quello del time sharing che permette l’uso del computer da parte di piu’ utenti alla volta che di solito agiscono da terminale (modo interattivo). Ciascun utente ha il diritto di usare il computer per una frazione di tempo, che dipende dal numero totali di utenti presenti in quel momento, ed interagisce direttamente col computer. Dato che il terminale ha bassa velocita’ di input (dovuto soprattutto alla lentezza umana ma anche alla bassa velocita’ intrinseca del terminale rispetto ad una CPU) il computer puo’ servire piu’ utenti alla volta senza che quest’ultimi in pratica ne risentano troppo. 26* Sistema operativo Ogni computer usa un proprio sistema operativo che non e’ altro che un programma sempre in funzione sulla macchina quando l’utente non sta facendo girare il proprio. Il sistema operativo permette al programmatore di definire tutte le operazioni che la macchina deve fare, come ad esempio compilare un file di istruzioni fortran (simbolico), eseguirlo, creare dei files, fare una lista dei files presenti in memoria, spedire un messagio per posta elettronica (e-mail) e mille altre funzioni (applicazioni). Quando un utente incomincia una sessione sul computer (login) il sistema operativo viene messo automaticamente in funzione. Il sistema operativo riconosce il linguaggio di controllo del lavoro (JCL) che l’utente dovra’ usare. Sfortunatamente fino a pochi anni fa ogni computer aveva JCL propri, e l’utente doveva impararsi i linguaggi di controllo per ciascun computer. Unix Un grosso passo avanti nella standardizzazione e’ stato compiuto con l’introduzione di UNIX, un sistema operativo concepito inizialmente nel 1969 da Ken Thompson e da allora sviluppato da molti ed oggi usato quasi universalmente. Una versione di Unix molto usata oggigiorno (ad es. sui PC) e’ LINUX . Esistono diverse versioni di JCL per Unix, che tra loro non differiscono moltissimo. Quelle oggi piu’ in auge si puo’ dire siano la Bourne shell (sh) , la C shell (csh) , la Korn shell 27* (ksh)). Noi useremo la C shell. Come cominciare una sessione dal PC del laboratorio a) Cercare l’applicazione Telnet e connettersi ad axppv1.pv.infn.it b) Eseguire il login : Trying 192.84.142.1 … Connected to decux1.pv.infn.it Escape character is ‘^]’ Digital UNIX (decux1.pv.infn.it) (ttyp1) username Password (non compare) login: boca Password: Last login: Wed Dec 29 20:09:56 from axppv1.pv.infn.it Digital UNIX V4.0D (Rev. 878); Tue Dec 28 16:36:44 MET 1999 ******************************************************************* decux1> 28* D’ora in avanti la notazione in blu verra’ usata per indicare i caratteri che vengono scritti al terminale in input dall’utente, in verde i caratteri scritti in risposta dal computer, mentre la notazione in corsivo verra’ usata per simboleggiare dei caratteri da scrivere o per indicare cose da fare da parte dell’utente Cambiare la password La password deve avere da 6 a 8 caratteri (in molti computers puo’ essere piu’ lunga). Comando : passwd L’utente BOCA vuole cambiare la sua password passwd Changing password for boca. Old password: vecchia password New password: nuova password Verification: riscrivo la nuova password per sicurezza 29* Directories In memoria, per esigenze di ordine e comprensione, e’ molto utile organizzare gruppi di files in directories. Questo significa che ogni file viene associato ad una directory. In UNIX ciascun file viene di conseguenza identificato come segue : directoryname/filename Dopo che si e’ fatto il login nel computer ci si trova automaticamente nella home directory che, ad esempio, per l’utente boca su axppv1.pv.infn.it si chiama /home/boca Se a questa directory fosse associato ad esempio il file prova allora il nome completo del file sarebbe /home/boca/prova Esistono comandi per associare un file ad una particolare directory, per fare la lista di tutti i files che appartengono ad una data directory, ed un comando per sapere in che directory ci si trova (cioe’ sapere qual’e’ la directory di default ). Directory di default significa la directory che viene sottointesa automaticamente - a meno che essa venga esplicitamente indicata - in tutti i comandi Unix. Percio’ se non ci sono esplicite indicazioni, quando si crea un nuovo file esso viene associato alla directory di default; quando si fa una lista di files esistenti tale lista e’ quella dei files associati alla direcotry di default ecc. ecc. 30* Sapere in che directory ci si trova (directory di default) Si usa il comando pwd pwd /home/boca questo e’ il nome della corrente directory di default Creazione di una nuova directory L’utente puo’ creare una nuova directory col comando mkdir pwd /home/boca mkdir dimostrazione A questo punto e’ stata creata una nuova directory il cui nome completo e’ : /home/boca/dimostrazione 31* cioe’ alla directory di default e’ stata aggiunta una / e poi il nome dimostrazione Cambio di directory Per cambiare la directory di default di usa cd pwd /usr1/users/boca cd dimostrazione pwd /usr1/users/boca/dimostrazione L’utente boca si trovava inizialmente nella directory /usr1/users/boca, quindi col comando cd ha definito come directory di default quella vecchia (/usr1/users/boca) + /dimostrazione e quindi ora si trova nella directory /usr1/users/boca/dimostrazione come e’ dimostrato dal susseguente comando pwd Elenco dei files appartenenti ad una data directory e/o aventi un certo nome Si usa il comando ls nomedirectory oppure ls nomefile 32* ESEMPIO ls /usr1/users/boca/cestino prova prova.bak prova1 prova1.bak L’utente boca ha richiesto l’elenco dei files appartenenti alla directory /usr1/users/boca/cestino ed il computer ha elencato i files esistenti cioe’ prova prova.bak prova1 e prova1.bak ESEMPIO pwd /usr1/users/boca/cestino ls prova prova.bak prova1 prova1.bak In questo secondo esempio l’utente boca si trovava gia’ nella directory /usr1/users/boca/cestino (come testimonia il comando pwd) ed ha mandato il comando ls senza specificare alcuna directory : il computer percio’ ha assunto come directory quella di default. Il risultato dell’elenco e’ percio’ identico a quello dell’esempio precedente. ESEMPIO ls /usr1/users/boca/cestino/prova prova In questo esempio l’utente ha richiesto una lista di uno specifico file. ESEMPIO ls /usr1/users/boca/cestino/pro* prova prova.bak prova1 prova1.bak In questo esempio si e’ richiesto l’elenco di tutti i files che iniziano per pro nella directory 33* /usr1/users/boca/cestino Si noti l’uso dell’asterisco (carattere speciale o metacarattere) che significa qualunque numero e tipo di carattere di seguito ai caratteri pro Compilazione di simbolici Fortran Per produrre un programma fortran bisogna tradurre il file ASCII che contiene le istruzioni in un file che contiene le istruzioni macchina. Per fare questo in UNIX c’e’ il comando f77 -static -o nomeoutput nomeinput ls prova.for f77 -static -o prova.exe prova.for ls prova.for prova.exe L’utente ha compilato (e ne ha anche fatto il linking) del simbolico (scritto in ASCII) contenuto nel file prova.for il risultato (programma eseguibile) e’ stato messo nel nuovo file prova.exe 34* Stampa del contenuto di un file ASCII a terminale Si possono usare diversi comandi per farlo. Ad esempio c’e’ cat nomefile oppure more nomefile con cat il file viene stampato interamente e di seguito, con more il file viene interamente stampato, ma con la possibilita’ di vederlo per pagine. Nomefile puo’ essere sia il nome completo del file (cioe’ con all’inizio la directory alla quale appartiene) oppure puo’ non avere la directory di appartenenza, nel qual caso il computer assume la directory di default. 35* Richiesta di istruzioni sull’uso di un comando In UNIX esite la possibilita’ di richiedere informazioni su come funziona un dato comando. L’istruzione da dare a terminale e’ man nomecomando Ad esempio, se si vogliono informazioni dettagliate sul comando ls basta battere man ls ed una lunga lista di istruzioni comparira’ sul terminale, con la possibilita’ di vederlo per pagine. Rimozione di un file Si usa il comando rm nomefile Al solito, se nomefile non e’ il nome completo di directory, viene assunta la directory di default. ls prova prova.bak prova1 prova1.bak rm prova.bak ls prova prova1 prova1.bak 36* L’utente ha rimosso dalla corrente directory il file prova.bak dalla directory di default, come e’ testimoniato dal comando ls eseguito dopo la rimozione Creazione di un file ASCII con un text editor Una necessita’ che si presenta spessissimo nell’uso di un computer, e’ il creare o modificare dei files ASCII. Il text editor e’ un programma che fa questo. Ci sono svariati tipi di text editors, noi useremo vi oppure nedit Il comando e’ vi nomefile oppure nedit nomefile dove nomefile puo’ essere sia un file nuovo che un file gia’ esistente. Come sempre, se la directory non e’ esplicitata nel nome del file, quella di default viene assunta. L’uso ed i comandi di vi ed nedit sono articolati e complessi e se ne puo’ avere il dettaglio con i comandi man vi oppure man nedit 37* Unix e’ concepito specialmente per macchine multiuser e multitasking Architettura di un sistema operativo Schematicamente un sistema operativo e’ fatto a strati, con un nocciolo di funzioni e programmi piu’ interne (kernel) e 3 strati via via piu’ esterni. Le funzioni del kernel controllano direttamente l’hardware del computer user interface utilities and tools (controllo della memoria e della system services CPU e delle varie periferiche). kernel Le funzioni dello strato system services chiamano le funzioni del kernel. Il linguaggio ASSEMBLER fa uso delle funzioni di questo strato. 38* A volte anche linguaggi a piu’ alto livello chiamano queste routines per ottenere maggiore rapidita’ di esecuzione. Il software dello strato utilities and tools rende la complessita’ delle chiamate alle routines del system service trasparente all’utente. In questo strato ci sono ad esempio i compilatori dei linguaggi ad alto livello ( fortran, C, C++, cobol, pascal, etc. ), la utilities mail od il tool dbx ( debugger di programmi fortran). Distinguiamo le utilities dai tools sulla base della maggior complessita’ delle prime rispetto ai secondi. Nello strato piu’ esterno infine, c’e’ l’interfaccia con l’utente cioe’ la shell o command language interpreter, che viene usato per impartire i comandi al computer. Le shell che sono diventate d’uso piu’ comune in Unix sono : Bourne shell C shell Korn shell ( sh ) storicamente la prima disponibile, che viene inclusa in tutte le versioni di Unix ( csh ) standard nei sistemi che usano il software Berkeley Software Distribution ( ksh ) standard per il software Sistem V ( AT&T) Le varie Unix shells differiscono tra loro per le funzioni che svolgono e per la sintassi dei loro comandi, ma tutte passano il controllo alle stesse funzioni al momento dell’esecuzione, con l’eccezione di alcuni comandi tipici di quella shell. 39* Come cambiare la shell di default Per cambiare la shell di default si usa il comando : chsh chsh changing shell for studente. Password: New shell [/bin/bash: /bin/tcsh Shell changed. 40* Processi e loro priorita’ Chiamiamo process un programma attivo. Quando un utente incomincia una nuova sessione a terminale, viene attivato il programma costituito dalla shell usata per default, che attende ed esegue i comandi dati da terminale. Questo e’ un esempio di process a cui il sistema assegna un numero ( process identifier ) che unicamente lo identifica.Questo process ha accesso alle risorse della macchina ( CPU, memoria, periferici ) con una certa priorita’ che gli viene assegnata dal sistema stesso. La parte del kernel responsabile dello scheduling la assegna dinamicamente, aggiornandola ogni pochi secondi, calcolandola con un algoritmo complesso, che si basa anche su una priorita’ di base data dal system manager all’utente. Parent process e child process Come gia’ detto, al momento del login viene attivato un process ( la shell ). Questo e’ un parent process . Quando diamo un comando da terminale, il process della shell viene interrotto ed un nuovo process, che esegue il comando, viene attivato. Quando quest’ultimo termina, il comando viene restituito alla shell, che riprende a funzionare. In Unix si dice che e’ stato generato un child process (quello che esegue il comando) da parte di un parent process (la shell).Questo meccanismo vien detto forking . Al child process viene assegnato un proprio process identifier number. Un child process puo’ a sua volta iniziare 41* un altro process, diventando a sua volta parent process di un child process. Multitasking in UNIX Multitasking ( o multiprocessing ) significa l’attivazione, da parte di un solo utente, di piu’ programmi contemporaneamente. In Unix il multitasking si ottiene quando un parent process fa il forking di uno o piu’ child process e tutti i process sono attivi contemporaneamente. Un esempio di multitasking e’ la stampa di un file alla line printer, durante la quale si possono eseguire altri comandi. In Unix ci possono essere piu’ process attivi o sospesi contemporaneamente, ma solo uno puo’ ricevere input da terminale. Questo si dice process in foreground mentre gli altri sono in background . NOTA BENE I processi attivi in background continuano anche quando il parent process che li ha lanciati esegue un logout dal computer. Se invece ci sono processi sospesi al momento del logout, allora un messaggio di avviso viene mandato a terminale ed il logout non viene eseguito. Se l’utente ripete il comando logout allora la sessione termina ed i processi interrotti vengono persi. 42* I comandi per fermare, mettere in background o portare in foreground un processo sono : 1) <ctrl>c termina un child process ( job ) che e’ attivo in foreground 2) <ctrl>z sospende l’esecuzione (ma non la termina) di un job che e’ attivo in foreground 3) & lancia un child process in background 4) fg n oppure fg %n porta in foreground un child process sospeso od attivo in background 5) bg n oppure bg %n fa diventare attivo un process sospeso e lo porta in background f77 -static -o myfile.x myfile.f compilazione e link del file fortran myfile.f <ctrl>z la compilazione viene sospesa Stopped messaggio a terminale, mandato del sistema, che avvisa della sospensione cat myfile.f stampa a terminale di myfile.f fg riporta in attivita’ in foreground, il process sospeso f77 -static -o myfile.x myfile.f messaggio a terminale che avvisa della ripresa della compilazione e link 43* Shell scripts Si definisce una shell script un ASCII file contenente dei comandi Unix. il seguente ASCII file e’ un esempio di shell script : ls -l * cat pippo mv pippo pluto In Unix si puo’ attivare una shell script semplicemente battendone a terminale il nome del file ASCII che la la contiene. Quando si attiva uno script, il sistema esegue ciascun comando dello script come se lo stessimo battendo da terminale Il comando << In una shell script, si usa il comando << label per indicare ad un programma quando finisce l’input che deve leggere. 44* immaginiamo di avere il programma myprogram.x che legge 5 numeri da terminale e ne fa la media. Si consideri la seguente shell script : …. myprogram.x << end 9.1 2.4 5.6 7.8 9.2 end …. Questo script, arriva all’esecuzione del comando myprogram.x ed il << fa si’ che tutte le righe a partire dalla successiva, fino a quella che precede la label end vengano considerate come dati in ingresso per il comando stesso. Se non ci fosse << end lo script prenderebbe input per myprogram.x da terminale (standard input). Piping La creazione di una pipe e’ un tipo particolare di attivita’, sincronizzata dal kernel, che coinvolge piu’ processes, nella quale l’output di un comando diventa input del comando che segue, senza bisogno di creare un file intermedio. Il piping e’ indicato dalla barra verticale | Questo comando e’ particolarmente utile e conferisce ad Unix una flessibilita’ 45* sconosciuta ad altri sistemi operativi. anticipiamo qui che il comando who elenca gli usernames che hanno attualmente una sessione aperta sul computer, mentre sort ordina alfabeticamente le righe di un testo ASCII. Infine more stampa il contenuto di un file (interpretato come file ASCII) ad una pagina per volta. who | sort | more questi tre comandi fan si’ che il kernel inizi 3 child process contemporaneamente, corrispondenti ai comandi who , sort , more. Tuttavia more aspettera’ input da sort che aspettera’ input da who . Quando l’output di who sara’ passato a sort , il child process responsabile di who finira’, e cosi’ quando in seguito sort avra’ passato tutto l’output a more, cessera’. Infine quando more avra’ finito di mandare output allo standard output, terminera’ ed il controllo ritornera’ al parent process. 46* Ridirezionamento dello standard input, output, error Come gia’ detto piu’ sopra, in Unix vengono definiti stdin input stream, solitamente la tastiera del terminale stdout output stream, solitamente lo schermo del terminale stderr device o file dove vengono mandati i messaggi di errore, di solito lo schermo del terminale. In Unix e’ possibile, in modo semplice, comodo ed elegante, ridirezionare stdin , stdout , stderr su devices o files che non siano quelli dati di default all’inizio della sessione (terminale), con i simboli della seguente tabella 47* simbolo > >! >> >>! >& >&! >>& >>&! < << xxx | | tee nomefile |& significato ridireziona stdout ridireziona stdout, senza tenere conto di noclobber ridireziona ed appendi stdout ridireziona ed appendi stdout senza dare errore e creando un nuovo file se ancora non esiste ridireziona stdout e stderr ridireziona stdout e stderr, senza tenere conto di noclobber ridireziona ed appendi stdout e stderr ridireziona ed appendi stdout e stderr senza dare errore e creando un nuovo file se non esiste di gia’ ridireziona stdin leggi l’input fino alla linea identica con xxx ridireziona stdout al prossimo comando (piping) ridireziona stdout, oltre che alla schermo, anche ad un file ridireziona stdout e stderr al prossimo comando 48* ls * > output questo comando fa si’ che l’output di ls * venga messo nel file (ASCII) output invece che visualizzato al terminale. Se il file output esistesse gia’, verrebbe sovrascritto dalla nuova versione ( in gergo Unix : clobbering ) e la vecchia versione verrebbe persa. L’utente puo’ impedire il clobbering (per evitare che uno sbaglio faccia perdere un file) con il comando set noclobber cosi’ che il sistema avvisa che il file esiste gia’ ed impedisce l’esecuzione del comando. Un altro esempio e’ dato da : ls -l * >! output ls -l pippo* >>& output dove prima viene ridirezionato l’output del comando ls -l * nel file output , facendo eseguire l’operazione ( grazie a ! ) anche se e’ stato fatto precedentemente set noclobber . Il secondo comando appende ( aggiunge ) il risultato del comando ls -l pippo* al file output. Anche eventuali messaggi di errore generati dal comando ls verrebbero stampati in output . 49* Nomi dei files in UNIX I nomi dei files e dei comandi Unix sono case sensitive . Le MAIUSCOLE precedono le minuscole. Esistono delle convenzioni, non obbligatorie, ma generalmente seguite, riguardo alle estensioni che si danno ai files estensione .a .bas .c .cc .f .h .l .o .p .s .y a.out significato libreria di objects source code di basic source code di C source code di C++ source code di fortran header file per il C programma di lex object file ottenuto dalla compilazione del source code source code per pascal source code di assembler programma id yacc programma eseguibile 50* Struttura dei comandi Unix Con poche eccezioni, la forma di un comando Unix e’ la seguente : nomecomando [ opzioni ] [ argomenti ] dove le [ ] significano che puo’ anche non esserci, e : • nomecomando sono generalmente lettere minuscole che caratterizzano il comando ; • le opzioni modificano l’azione del comando e di solito sono singole lettere precedute da - ; si possono combinare assieme e di seguito piu’ opzioni facendole precedere da un unico oppure separatamente, con uno spazio in mezzo e precedute da - Il comando ls -l -t fa una lista lunga ( opzione l ) di tutti i files presenti nella current directory ordinandoli temporalmente ( opzione t , i files piu’ recenti vengono elencati per primi). Stesso risultato si otterrebbe con ls -lt 51* L’argomento e’ generalmente l’oggetto su cui agisce il comando nomecomando , opzioni , argomento devono essere separati da spazi o tab che, tranne poche eccezioni, sono gli unici delimitatori validi in un comando Unix. Si definisce word quei caratteri compresi tra due delimitatori consecutivi. Un semplice comando Unix percio’, e’ una sequenza di una o piu’ words comprese tra spazi o tabs. Vengono definite words separate (anche se sono in compagnia di altri caratteri) i caratteri & | < > ; ( ) # I caratteri && || << >> vengono considerate come una ( non due ) word. il comando ls -lt e’ formato da 2 words, mentre il comando ls -lt | more e’ per Unix composto da 4 words. 52* Si possono mettere piu’ comandi su una stessa linea, separandoli con ; che, in questo caso, ha la stessa funzione del carriage return. i seguenti comandi pwd ; ls -lt sono equivalenti a pwd ls -lt Per continuare un comando sulla prossima riga si usa \ prima del return che termina la linea ( deve essere l’ultimo carattere prima del return ). 53* Devices, directories e struttura dei files In Unix un file e’ identificato in maniera piu’ generale da host:/ directory / filename dove host: nome del computer dove il file risiede. Di solito host: si omette e viene usato solo da comandi come rcp o scp directory nome della directory alla quale il file appartiene filename nome del file • Si definisce file system un insieme di files e directories organizzato gerarchicamente, con una directory principale in cui ci possono essere files ed altre directories ; in quest’ultime ci possono essere altre directories, etc. • / e’ il root file system 54* In Unix non c’e’ la necessita’ di esplicitare il nome del device dove il file fisicamente risiede (tranne nel caso sia un nastro). Il sistema Unix determina dove si trova il file andando a leggere /etc/fstab che e’ il file sysem table, dove sono registrati su quali dischi stanno fisicamente tutti i file systems. il seguente e’ un esempio di /etc/fstab 55* Il sistema utilizza /etc/fstab ad ogni reboot del computer per montare (assegnare) i vari devices fisici sugli appropriati file systems. L’utente puo’ controllare con df i file systems montati ed anche la percentuale di spazio rimasto a disposizione. questo e’ un esempio del printout generato da df 56* Nomi comunemente dati ad alcuni devices I devices piu’ comunemente usati, hanno in Unix nomi leggermente variabili a seconda della particolare implementazione e computer. Un esempio e’ dato nella seguente tabella nome device /dev/ra0 /dev/rra0 /dev/console /dev/tty01 /dev/printer /dev/mt0 /dev/rmt0 /dev/null descrizione disk drive ( block ) disk drive ( character ) system console asynchronous terminal default system printer tape drive ( block ) tape drive ( character ) cestino Da notare l’esistenza di /dev/null che funziona da cestino. Mandandogli dell’output od un file, questo viene perso. Analogamente, se si legge da /dev/null si ha subito un end of file. Il comando cp /dev/null myfile 57* ha l’effetto di creare il file myfile che e’ vuoto. Nomi comunemente dati ad alcuni directories In Unix vi sono delle convenzioni, solitamente seguite, sul nome da dare a directories che contengono particolari files, vedi tabella seguente. nome directory /bin /dev /etc /lib /tmp /usr/adm /usr/bin /usr/dict /usr/share/man /usr/spool /usr/tmp contenuto files eseguibili di sistema, frequentemente usati files speciali, che indirizzano devices miscellanea di files vari files di librerie files temporanei ( scratch files ) files amministrativi di sistema files eseguibili di sistema, meno frequentemente usati files del dizionario files del manuale man files che devono essere spooled ( scaricati ) alle code stampanti files di swap e page 58* Definizioni assolute e relative di files La definizione esplicita di un file Unix per mezzo del nome completo a partire dalla root directory / e’ detta definizione assoluta del file. Come gia’ detto altre volte, delle / delimitano il directory pathway attraverso tutte le sottodirectories. Tutte le definizioni di files che cominciano con / sono assolute. Invece, le definizioni che partono dalla current directory si dicono definizione relativa di un file e non cominciano mai con la barra. /home/boca/cestino/prova cd /home/boca/cestino ls prova e’ un esempio di definizione assoluta di un file questo e’ un esempio di uso della definizione relativa di un file 59* ls -l /home/boca/cestino questo e’ un esempio di ricerca dei files contenuti nella directory, indicata con definizione assoluta, /home/boca/cestino cd /home/boca ls -l cestino questo e’ un esempio di ricerca di files contenuti nella stessa directory indicata, questa volta, con una definizione relativa a partire dalla directory /home/boca ls ~boca la ~ seguita da uno username ( boca ) indica la home directory dell’utente ( in questo caso /home/boca ). Questo e’ un esempio di filename substitution (globbing ). Questo comando e’ in definitiva equivalente a ls /home/boca cd /home/boca/cestino ls -l ../bin il doppio punto ( .. ) indica la directry appena sopra ( altro esempio di globbing). Il comando percio’ equivale a ls -l /home/boca/bin cd /home/boca ls -l . il singolo punto indica la presente directory. Il comando percio’ equivale a ls -l Anche questo e’ un altro esempio di globbing. 60* Tipi di files in Unix Ci sono 3 tipi di files in Unix : i files speciali , i files ordinari ed i directory files. a) Tutti i devices ( dischi, tape drivers, printers, terminali, e pseudoterminali - quelli usati durante le connessioni alla rete ) vengono trattati come files speciali i quali, come gia’ visto in precedenza, risiedono nella directory /dev Si ottiene un printout sulla line printer, ad esempio, scrivendo allo special file che individua la line printer. Questo normalmente viene fatto tramite i comandi della C-shell, ma in alcuni casi l’utente lo puo’ fare anche direttamente. b) I files ordinari contengono caratteri ASCII o binari. Copiando un file ordinario in uno special file, si otterra’ l’output del contenuto sul device associato allo special file. Di default Unix NON formatta il file ( cioe’ non aggiunge bits al contenuto del file ) tranne per un <ctrl>D ( end of file ) alla fine del file. Casomai puo’ essere il comando o programma usato dall’utente ad interpretare o scrivere in certo modo i dati ( si pensi alla scrittura ASCII dei caratteri col Fortran 77, ad esempio ). c) Dei directoy files si e’ gia’ parlato. Un directory file ha una entry per ciascun file contenuto nella directory ed oltre al nome del file ed altre informazioni, contiene anche l’ inode del file. Quest’ultimo e’ un numero che unicamente identifica ciascun file ( si puo’ vedere l’ inode con il comando ls -i nomefile ). 61* Hidden files Sono una particolare classe di files ordinari, e cominciano il loro nome con un punto ( . ) Il loro nome e’ dovuto al fatto che non vengo listati dal comando ls a meno che non si usi l’opzione -a ( list all ). La tabella che segue fa un sommario dei principali hidden files e della loro funzione. Il motivo per cui sono ‘nascosti’ e’ che cosi’ l’utente ha meno probabilita’ di danneggiarli …. In realta’ l’utente li puo’ modificare per farli aderire alle proprie esigenze. Generalmente si trovano tutti nella directory $HOME dell’utente. 62* nome hidden file funzione eseguito all’inizio della sessione, ma dopo aver eseguito il .login di sistema e prima di aver chiamato il file $HOME/.login Solo se si usa la C-shell viene chiamato .cshrc Usualmente si usa per definire environmentals, alias e definire altre opzioni e paramentri. .exrc definizione degli environmentals per l’editor ex .forward definisce il forwarding address per il mailer .history contiene la history list .hushlogin disabilita alcuni messaggi di login .login viene eseguito all’inizio della sessione, qualunque sia la shell di default usata dall’utente. Qui si definiscono environmentals e si settano preferenze etc. che vanno usate indipendentemente dalla particolare shell usata. .logout viene eseguito subito prima del termine della sessione. Qui l’utente mette tutto cio’ che vuole eseguire appena prima della chiusura della sessione. .mailrc contiene le definizioni degli environmentals per il programma mail .netrc contiene i parametri per il programma ftp .profile analogo al file .cshrc tranne che viene eseguito ( dopo il .login sistema) se si usa la Bourne shell .rhosts vengono indicati gli utenti e macchine remote alle quali lo user permette di accedere al computer tramite il proprio account. 63* .cshrc Caratteri speciali In Unix alcuni caratteri vengono interpretati in modo speciale dalla shell e vengono chiamati metacaratteri. La tabella che segue ne elenca alcuni di quelli non citati precedentemente per il redirecting ; quelli asteriscati hanno un significato speciale solo per la C-shell. Da notare che il significato di un metacarattere puo’ variare a seconda che venga interpretato dalla C-shell o da una Unix utility. 64* Il metacarattere * ( wildcard ) ha in generale il significato di sostituzione di un numero arbitrario di caratteri arbitrari (vedi in seguito) ; il suo effetto tuttavia puo’ differire leggermente a secondo del comando Unix che lo usa. ls * questo comando produce la lista di tutti i files della directory corrente e delle directories ad un livello piu’ basso nella gerarchia delle directories ( in questo caso * ha un effetto maggiore che la semplice sostituzione ). Invece il comando wc * produce il word counting per tutti e solo i files della directory corrente. Il comando ls . invece, fa la lista della directory corrente soltanto, mentre wc . interpreta il (se esiste). . letteralmente andando a fare il word counting di un file di nome 65* . TABELLA DEI METACARATTERI ( I ) metacarattere & && = == != =~ !~ <= >= || ; \ \m ‘ ` “ # ! % * ? funzione esegue il comando in background and Booleano operatore di assegnazione uguale a ; e’ una comparazione di stringhe di caratteri diverso da ; e’ una comparazione di stringhe di caratteri simile a ; e’ una comparazione di stringhe di caratteri dissimile da ; e’ una comparazione di stringhe di caratteri minore od uguale a maggiore od uguale doppia barra ; or Booleano separatore di comandi comando di continuazione della linea di comando traduzione letterale del metacarattere m togli il significato speciale esegui immediatamente raggruppa i caratteri in un unico comando seguono dei commenti fino al prossimo carriage return history substitution significa un job in background wildcard , sostituzione di qualunque numero e tipo di caratteri wildcard, sostituzione di un singolo carattere 66* TABELLA DEI METACARATTERI metacarattere $ $# $$ $? $< @ ~ [] . {} ( II ) funzione segue una sostituzione di argomento numero di argomenti passati ad uno shell script Process ID Exit status legge una linea da stdin esegui un calcolo numerico home directory substitution filename selective substitution current directory delimitatore usato in vari comandi NOTA BENE • Facendo precedere un metacarattere da \ ha l’effetto di toglierne il significato speciale (il metacarattere viene interpretato come carattere normale). • Facendo precedere \ ad un carriage return si fa diventare quest’ultimo equivalente ad uno spazio. • I caratteri racchiusi tra “ (double quotes) oppure ` (grave accents) oppure ‘ (single quotes) formano UNA word. I metacaratteri racchiusi non formano word separate. E’ possibile includere il carattere carriage return tra apici o apici doppi, a patto67* di farlo precedere da \ Wildcards In Unix alcuni metacaratteri vengono usati come wildcards, tipicamente per indicare nomi di files. La wildcard non viene presa letteralmente dal sistema, ma ad essa vengono sostituiti uno o piu’ caratteri. Le wildcard in uso nella C shell sono indicate nella tabella seguente TABELLA DELLE WILDCARDS wildcard * *.com pipp* *.* ? ?.com prova[xyz] prova[a-z] prova[a-z4] prova{o,f} funzione nome composto da un qualunque numero di caratteri qualunque qualunque nome di file che termini in .com qualunque nome di file che inizia con pipp qualunque nome di file che contenga almeno un . sostituzione di UN (solo uno!) carattere qualunque qualunque nome di file che termini in .com preceduto da un carattere qualunque le [] indicano sostituzione di uno dei caratteri contenuti nelle parentesi. Quindi in questo caso indica il nome di file provax oppure provay o oppure provaz un qualunque nome tra quelli da provaa fino a provaz un qualunque nome tra quelli da provaa fino a provaz piu’ prova4 68* stesso significato di prova[of] Quando si inizia una sessione Unix, occorre definire un certo numero di environmentals o variabile di ambiente indispensabili per poter lavorare (vedi qualche trasparenza piu’ sotto la spiegazione delle variabili d’ambiente). Fortunatamente, in genere l’utente non deve preoccuparsi di queste definizioni che vengono effettuate dal login di sistema, e dalla esecuzione automatica della .cshrc e del .login che risiedono nella propria home directory. 69* Operazioni del sistema al momento del login Quando il prompt del login appare sullo schermo, e l’utente fa il login, il sistema Unix compie un certo numero di operazioni : il programma /etc/init legge una lookup table che si trova in /etc/ttys e che contiene una stringa per ogni device del tipo terminale ( /dev/tty ) o pseudo-terminale ( /dev/ptty ) disponibi le al sistema. Unix usa un descrittore di 5 caratteri : tty che indica terminale, poi un esadecimale per il numero di controller, un altro esadecimale per il numero di linea ( ad es. tty01 o ttyff ). Si puo’ usare il comando tty per sapere il nome del proprio terminale. Poi /etc/init passa la stringa corrispondente al terminale al programma /etc/getty che controlla se al nome del terminale corrisponde un’entry nella lookup table /etc/gettytab ed in caso positivo legge i parametri del terminale ( baud rate, parity, funzione del tasto <break> , etc. etc. ) altrimenti ne assegna di default. 70* Quindi /etc/getty passa il controllo a /bin/login che chiede all’utente la password e la confronta con quella ( incriptata ) contenuta nel file /etc/passwd e quindi, in caso positivo, assicura il permesso ad entrare nel sistema. Inoltre /bin/login updata le informazioni di accounting e cerca nel file /etc/group a quale gruppo l’utente appartiene. Un utente Unix puo’ appartenere a piu’ gruppi. L’appartenere ad un certo gruppo fa si’ che tutti i files dell’utente abbiano di default un certo tipo di protezione group level distinta da quella world level e da quella user level . Si puo’ usare il comando groups per sapere a che gruppo si appartiene. Quindi /bin/login invoca il programma /etc/environ che assegna le variabili di ambiente ( environmentals ) del sistema. Infine /bin/login sempre grazie all’informazione contenuta in /etc/passwd assegna una copia della shell di default al’utente. Normalmente la Bourne shell ha come prompt il $ , mentre la C-shell ha il % In Unix tutti gli utenti hanno lo stesso tipo di privilegi, eccetto il superuser con login name root che ha tutti i privilegi possibili ( e che normalmente e’ il manager del sistema). Quando un utente si collega, appaiono allo schermo un certo numero di messaggi di sistema che si possono eliminare creando il file ( anche vuoto ) .hushlogin nella propria home directory. 71* Come detto, il file /etc/ttys contiene le informazioni relative al terminale usato dalla presente sessione, incluso il tipo di terminale ( ad es. vt100 ). A questo terminal descriptor corrisponde una entry in un altro file, /etc/termcap nel quale ci sono altre informazioni su un gran numero di tipi di terminali di marche diverse. Queste informazioni sono in genere sufficienti perche’ la shell funzioni adeguatamente su quel terminale. In ogni momento della sessione l’utente puo’ cambiare quelle specifiche. Nelle situazioni in cui terminali differenti usano la stessa porta del computer (ad es. linee per modem, network connections, etc.) Unix fa corrispondere una generica definizione in /etc/ttys (ad es. dialup o network) ad una generica definizione in /etc/termcap . Poi l’utente potra’ modificare le caratteristiche del proprio terminale usando i comandi tset (che assegna le caratteristiche di input/output ad una sessione da terminale) e/o stty (che assegna le caratteristiche alla tastiera). Tali comandi sono piuttosto complicati. Ricordiamo qui solamente che setty e tset senza opzioni fanno una lista delle caratteristiche correnti assegnate al terminale ed alla tastiera. 72* Variabili d’ambiente (environmentals) e shell variables Definizione di environmental o ( variabile d’ambiente ) : e’ una variabile, assegnata ad un process, che viene conservata in una locazione di memoria del computer. Questa varibile ha un valore, assegnato dall’utente o dal sistema; le varibili d’ambiente valgono qualunque sia la shell usata dall’utente. Come assegnare, deassegnare, stampare il valore di una variabile d’ambiente L’utente puo’ definire e/o assegnare un valore ad un environmental col comando setenv ENVIRON valore dove ENVIRON e’ il nome della variabile, valore e’ il valore dato alla variabile. Una convenzione spesso seguita in Unix e’ quella di usare tutte lettere maiuscole per i nomi degli environmentals. Si puo’ eliminare una variabile d’ambiente con unsetenv ENVIRON e si puo’ stampare il valore di un environmental con printenv ENVIRON mentre printenv senza argomenti, stampa a terminale tutti gli environmentals definiti per il processo corrente. Si puo’ anche usare il comando : echo $nomeenvironmental dove nomeenvironmental e’ il nome della variabile. Si noti l’uso del metacarattere $ che 73* attua un argument substitution . setenv DEMO pincopallino printenv DEMO pincopallino unsetenv DEMO printenv DEMO l’ultimo comando non produce output dato che la variabile DEMO e’ stata appena cancellata dall’utente col comando unsetenv L’utente boca ottiene la seguente stampa dopo aver dato printenv senza argomenti : 74* Shell variables Queste variabili sono analoghe agli environmentals eccetto che vengono definite ed hanno validita’ solo nell’ambito della shell correntemente usata dall’utente ( ad es. la C-shell ) cessando di esistere, per esempio, se l’utente cambia shell. Come assegnare, deassegnare, sampare il valore di una variabile di shell Nella C-shell l’utente puo’ usare il comando set shellvar = valore E’ una convenzione spesso usata in Unix di adoperare le lettere minuscole per definire le variabile di shell . Per eliminare una variabile di shell si usa unset shellvar e per stampare il valore di una shell varible si usa echo $shellvar ( notiamo il $ che e’ quello special character usato per l’ argument substitution ) mentre set senza argomenti stampa il valore di tutte le shell variables definite. 75* set prompt = “`hostname` >” decux1.pv.infn.it> l’utente ha posto nella shell variable prompt (che poi viene stampata automaticamente dal sistema all’inizio di ogni nuova linea di comando) il valore dato dal risultato del comando hostname piu’ il simbolo > 76* L’utente boca ottiene la seguente stampa dopo aver dato il comando set senza argomenti 77* Environmentals piu’ comunemente definiti al momento del login di sistema Come visto precedentemente, il file /etc/environ viene eseguito dal sistema al momento del login per assegnare gli environmentals di sistema necessari per far funzionare la sessione. Nella tabella seguente sono elencati nome e significato di quelli piu’ comunemente definiti. TABELLA DEGLI ENVIRONMENTALS COMUNEMENTE DEFINITI DAL SISTEMA nome environmental HOME SHELL TERM USER LOGNAME PATH EDITOR MAIL significato home directory pathname per la shell usata di default tipo di terminale user name login name directories in cui cercare al momento di eseguire comandi non built-in editor di default 78* directory dove controllare se ci sono mail messages Particolare importanza riveste l’environmental PATH che e’ usato dal sistema quando l’utente manda un comando che non sia built-in. In questo caso il comando (che altro non e’ che un programma) viene cercato nelle directories specificate da PATH, nell’ordine con cui sono scritte . Ciascuna directory e’ separata dalle altre da : (due punti). Variabili di shell comunemente impiegate quando si usa la C-shell Molte delle shell variables assegnate dal sistema quando un’utente invoca la C-shell hanno lo stesso nome (ma scritto in minuscole) e stesso significato degli environmentals corrispondenti. Un esempio e’ la variabile home che solitamente corrisponde a HOME Nella tabella seguente sono elencate le variabili piu’ comunemente definite nella C-shell ed il loro significato. Per togliere l’effetto di tali variabili bisogna usare il comando unset 79* TABELLA DI ALCUNE SHELL VARIABLES COMUNEMENTE DEFINITE nome della significato shell variable set autologout = n specifica il numero di minuti di idle time prima che una shell interattiva termini set echo ripete i comandi dati dall’utente set history = n ricorda gli ultimi n comandi impartiti dall’utente set home = string assegna la home directory per la C-shell set ignoreeof impedisce che <ctrl>D faccia il logout della sessione set mail = string assegna la directory dove vengono messi i mail messages set noclobber impedisce la sovrascrittura accidentale durante la redirection set noglob impedisce l’espansione dei filenames set notify avvisa di quando un job e’ finito set path = string path in cui ricercare i comandi della C-shell set prompt = string assegna il prompt per la C-shell set savehist = n ricorda gli ultimi n comandi all’inizio di una nuova sessione set shell = string file dove si trova la shell status variabile che viene messa = 0 ( = buon esito del comando) od ad un valore diverso da 0 (errore) quando finisce l’esecuzione di determinati comandi set time = n per ogni comando che duri piu’ di n secondi viene riportato il CPU time e l’elapsed time set verbose le parole usate per ciascun comando vengono ripetute 80* Funzione degli hidden files .login, .cshrc e .profile L’hidden file .cshrc viene eseguito dopo il login di sistema, e nel caso che l’utente usi la C-shell per default. Se invece viene usata la Bourne shell, allora viene eseguito il file .profile In entrambi i casi, successivamente viene eseguito un altro hidden file, il .login Tutti questi file si trovano nella propria home directory e l’utente puo’ modificarli per far eseguire quei comandi o assegnare environmentals o shell variables all’inizio della sessione. Ogni volta che c’e’ un forking il child process riceve tutti gli environmentals definiti nel login di sistema, nel .login e nel .cshrc (inoltre riceve tutte le definizioni di comandi definiti con alias , vedi seguito). Questo succede ad es. quando l’utente impartisce un comando che non sia built-in nella shell in uso causando cosi’ il forking di un child process che esegue il comando. Comando alias Serve per abbreviare o comunque dare un nome equivalente ad un comando. Sintassi : alias nickname comando dove nickname e’ il nuovo nome del comando comando. 81* alias ll “ls -l” dopo questo aliasing quando l’utente impartisce il nuovo comando ll il comando ls -l e’ come se battesse Esempio di .cshrc file Il seguente .cshrc file assegnera’ nuovi valori alle varibili sevehist , mail e prompt e definisce i nuovi comandi ll e ce set savehist = 50 set mail = $MAIL set prompt = “! $USER” alias ll ls -l alias ce “cd ~boca/cestino ; pwd” Esempio di .login file Qui vengono ridefiniti gli environmentals SHELL , TERM , EDITOR , MAIL setenv SHELL /bin/csh setenv TERM vt100 setenv EDITOR /usr/local/bin/X11/nedit setenv MAIL /usr/spool/mail/boca 82* Operazioni del sistema al momento del logout L’utente puo’ finire la sessione in due modi : con il comando logout o con il comando <ctrl>D se ignoreeof non e’ stato assegnato (vedi sopra). <ctrl>D e’ un marker di end of file e percio’ quando la shell lo vede termina di funzionare (e cominciano le operazioni di logout). In ogni caso, prima di terminare la shell esegue (se c’e’) una altro hidden file che risiede nella home directory che e’ .logout In questo file l’utente puo’ mettere quei comandi che vuole che siano eseguiti prima che termini la sessione, come ad es. clear che ‘rinfresca’ lo screen del terminale. Dopo aver eseguito il .logout il sistema esegue il file /etc/logout per le eventuali ultime operazioni richieste dal sistema ed infine ripassa il comando al programma /etc/init (lo stesso che era stato attivato al momento del login ) per finire la sessione in modo standard. Come gia’ accennato precedentemente, non e’ possibile il logout se ci sono stopped process (il comando jobs fa una lista di tutti i process attivi e stopped). Tuttavia se il comando logout viene ripetuto la seconda volta, la sessione finisce ed gli stopped 83* processes vengono persi. Come richiamare i comandi precedenti Trattiamo qui quali sono le possibilita’ di history substitution in Unix. Comandi di history substitution in Unix (I) comando history !! !n !string !?string? !-n significato fa una lista degli ultimi comandi impartiti (history list) esegue il comando precedente esegue l’ n-esimo comando nella lista della storia dei comandi esegue l’ultimo comando che incomincia con string esegue l’ultimo comando che contiene string esegue l’ n-esimo comando precedente 84* history 1 18:30 ls -l -t 2 18:34 set ignoreeof 3 18:35 ls prova.f 4 18:36 more prova.f 5 18:40 vi prova.f 6 18:43 history se ora l’utente impartisce da tastiera l’ordine !! ritornera’ ad eseguire il comando history che aveva precedentemente eseguito. Se invece impartira’ il comando !1 tornera’ ad eseguire ls -l -t Se invece battesse a terminale !ls avrebbe come effetto di ripetere il comando ls prova.f Se battesse invece il comando !?rov? ritornerebbe ad eseguire il comando vi prova.f mentre se battesse !-5 verrebbe eseguito ancora set ignoreeof 85* Negli esempi seguenti vengono elencati comandi di history substitution in cui vengono invece richiamate words appartenenti a comandi precedenti history 1 18:30 ls file1 file2 file3 Nel comando precedente, ls e’ la word n. 0 , file1 e’ la word n. 1 etc. Se ora l’utente impartisce da tastiera l’ordine cat !1:1 ottiene come effetto l’equivalente di cat file1 ovvero viene sostituita, al posto di !1:1 , la word 1 del comando n. 1 della history list. Se invece impartisce l’ordine cat !1:* ottiene cat file1 file2 file3 (sostituzione di tutte le words da 1 in avanti del comando n. 1); invece, con cat !1:$ si ottiene cat file3 (sostituzione dell’ultima word); mentre con cat !1:2-3 si ottiene cat file2 file3 (sostituzione delle words da 2 a 3); infine con cat !1:2-3 file10 si ottiene l’equivalente di cat file2 file3 file10 (espansione della linea 86* di comando con nuovi argomenti). Infine, supponendo di impartire il comando cat file1 file2 file3 e susseguentemente ls !* si ottiene ls file1 file2 file3 cioe’ la sostituzione di tutte le words > 0 del comando precedente. 87* Gli esempi che ora seguono implicano la sostituzione di nuove words in comandi precedenti. sintassi : ^string1^string2 esempio : cat file1 ^cat^ls ls file1 !n:s/string1/string2/ history …. 7 18:31 cat file1 …. !7:s/cat/ls/ ls file1 !n:p:s/string1/string2/ sintassi : esempio : sintassi : esempio : !! !7:p:s/cat/ls ls file1 !! ls file1 sostituisce string2 a string1 nel comando precedente sostituisce string2 a string1 nel comando n sostituisce string2 a string1 nel comando n ma senza eseguire il comando risultante, solo facendolo vedere comunque aggiungendolo alla history list esegui il comando precedentemente mostrato 88* Help online ( comando man ) In Unix esiste il comando man per ottenere informazione su un comando, una funzione, etc. L’output di questo comando ha in generale la forma (ma non per tutti i comandi e’ uguale, ci possono essere piu’ o meno dei paragrafi qui elencati) : NAME SYNOPSIS OPTIONS OPERANDS DESCRIPTION SEE ALSO EXAMPLES BUGS RESTRICTIONS AUTHORS nome del comando e suo proposito sommario del suo uso elenco delle possibili opzioni usabili con questo comando elenco degli operandi su cui agisce il comando descrizione in piu’ dettaglio del comando altri luoghi nel manuale dove trovare informazioni relate esempi d’uso del comando descrizione di bachi conosciuti, deficienze e modi di aggiustarli se sono disponibili limitazioni che si conoscono autori del codice del comando Le pagine di man risiedono nelle directories da /usr/share/man/man1 a /usr/share/man/man8 secondo la classificazione mostrata nella seguente tavola. Ad es. la man page per il comando cat si trova in /usr/man/man1/cat.1.gz 89* Tavola delle pagine di man numero di pagina 1 2 3 4 5 6 7 8 contenuto comandi della shell funzioni di sistema (kernel access points) librerie di subroutines descrizione degli input/output device driver include files e formats computer games special files system procedures Inoltre, le sezioni 1 e 3 sono suddivise come segue 1 comandi general purpose 1c comandi relati alla comunicazione 1g comandi relati alla grafica 1m comandi di system maintenance 3 3f 3m 3r 3s 3x libreria standard di subroutines routines di supporto del FORTRAN 77 subroutines di matematica librerie per internet network subroutines di input/output subroutines varie 90* Ci sono 4 modi di usare man : • sintassi man comando esempio man cat nell’esempio sopra riportato, il computer cerca le pagine di man che si riferiscono al comando cat e l’output viene mandato a terminale • sintassi man -k keyword esempio man -k terminal in questo esempio vengono listate tutte le informazioni relative alla parola chiave terminal. Il comando man -k puo’ anche essere sostituito dal comando apropos • sintassi man -f comando esempio man -f more questo comando produce una breve descrizione del comando more. Il comando man -f e’ equivalente al comando whatis • sintassi man sezione comando esempio man 3 stty in quest’ultimo esempio l’utente sa gia’ in quale sezione di man si trova l’informazione cercata e ne fa il display a terminale. 91* Unix possiede numerosi comandi ed utilities per la creazione, modifica, il display di files e directories. La tabella che segue riassume i comandi e le routines chiamabili da un programma scritto in Fortran 77 oppure da un programma scritto in C , per il file management. Sono sottolineati quei comandi di cui in particolare tratteremo, gli altri si possono approfondire con le pagine di man . Nella tabella vengono anche divisi i comandi che fanno un display di files o di loro caratteristiche, da quelli che li manipolano. L’utente novizio puo’ usare i primi in tutta sicurezza in quanto i files non vengono modificati, mentre per quanto riguarda i secondi, si dovra’ prestare piu’ cura poiche’ il contenuto dei files potrebbe essere modificato. 92* TABELLA DEI COMANDI O ROUTINES PER IL MANAGEMENT DI FILES E DIRECTORIES Display commands nome comando o routine cat col colcrt fmt fold head ls more od pr tail significato stampa allo standard output del contenuto di un file filtra i reverse line feed filtra nroff output per CRT (cathodic ray tube) text formatter spezza linee lunghe di un file in piu’ linee di larghezza prefissata stampa le prime linee di un file lista dei file esistenti e/o del contenuto di directories stampa allo standard output del contenuto di un file, a pagine per volta stampa allo standard output del contenuto di un file in ottale, decimale, esadecimale od ASCII stampa files allo stdout stampa l’ultima parte di un file allo stdout 93* TABELLA DEI COMANDI O ROUTINES PER IL MANAGEMENT DI FILES E DIRECTORIES Manipulation commands riguardanti directories nome comando significato cd chdir getdirentries cambia la current directory cambia la current directory - anche C callable routine trova le directory entries con formato indipendente dal file system C callable routine getwd trova il path name del current directory - C callable routine mkdir crea una nuova directory pwd stampa il path name della current directory rmdir rimuove una directory scandir, alphasort esamina una directory - C callable routine unlink rimuove una directory entry in una directory ; sia comando che C callable routine Manipulation commands riguardanti files (I) ar comando che opera su librerie awk pattern scanning and processing language basename isola la base di un filename bcopy, bcmp, bzero, ffs operazioni con stringe di bit o byte ; C callable routines 94* TABELLA DEI COMANDI O ROUTINES PER IL MANAGEMENT DI FILES E DIRECTORIES Manipulation commands riguardanti files (II) nome comando significato checknr controlla files prodotti da nroff e/o troff chgrp cambia il gruppo associato con un file o con una directory chmod cambia la protezione di un file o directory ; sia comando che C routine cmp confronta due files per scoprirne le differenze comm seleziona od elimina linee comuni a due files cp copia di un file o directory creat crea un nuovo file ; C callable routine crypt comando per incrittare o decriptare files crypt, setkey, encrypt operazioni per incrittare / decriptare ctags creazione di un tag file dd conversione e copia di un file diff confronto di 2 files ASCII diff3 confronto di 3 files ASCII expand, unexpand sostituisce gli spazi con i tabs o viceversa file determina il tipo di file (ASCII, eseguibile, command file etc.) find trova files flock applica o rimuove un advisory lock su un file aperto ; C callable 95* routine TABELLA DEI COMANDI O ROUTINES PER IL MANAGEMENT DI FILES E DIRECTORIES Manipulation commands riguardanti files (III) nome comando ftp grep, egrep, fgrep ident link ln lockf look merge mknod mktemp mv ncheck nroff open qsort ranlib significato programma per trasferire files da un computer ad un altro ricerca di un pattern in un file identifica files crea un link ad un file - C callable routine crea links per files crea un nuovo file ; C callable routine trova linee che cominciano con una certa stringa di caratteri, in files merge di files crea special files ( character, block, fifo ) crea un file il cui nome sia unico - C callable routine rinomina un file elenca inode numbers e nomi di tutti i files in un file system formatta del testo apre un file per read o write ; C callable e Fortran callable routine ordina una tabella ; C callable routine converte archivi in random libraries veloci da consultare da parte 96* di un linker TABELLA DEI COMANDI O ROUTINES PER IL MANAGEMENT DI FILES E DIRECTORIES Manipulation commands riguardanti files (IV) nome comando significato rcp, scp copia di files su una macchina remota read legge una linea di input da stdin readv legge input da stdin ; C callable routine readlink stampa il contenuto di un file symbolic link (a che punta il link) rename cambia nome ad un file; C callable routine rev scrive al contrario le linee di un file size scrive la grandezza di un object file sort ordina o fa il merge di files split spezza files in piu’ pezzi stat, lstat, fstat ottiene informazioni sullo stato di un file ; C callable routine strncpy, strlen, undex, rindex operazioni con le stringhe di bytes ; C callable routine strings conversione e copia di un file sum somma e conta i blocchi in un file swab fa lo scambio di bits ; C callable routine symlink crea crea symbolic links ad un file ; C callable routine tar tape archiver tr character translator touch crea un file vuoto od updata la data dell’ultima modifica di un file 97* troff formattamento di un testo TABELLA DEI COMANDI O ROUTINES PER IL MANAGEMENT DI FILES E DIRECTORIES Manipulation commands riguardanti files (V) nome comando significato truncate, ftruncate tronca un file ad una lunghezza prefissata ; C callable routine tsort ordinamento topologico umask definisce le protezioni di default per i files creati uniq riporta e/o cancella le linee che si ripetono in un file utime assegna la data di accesso e di modifica ad un file ; C callable routine utimes assegna la data di accesso e di modifica ad un file ; C callable routine wc conteggio delle parole in un file what mostra che versioni di objects sono state usate per costruire un file which trova il file corrispondente ad un comando, incluso alias e path 98* Elenco del contenuto di una directory ( ls ) Il comando ls viene usato per elencare files, directories e loro caratteristiche. Sintassi ls [-options] [arguments] Negli esempi che seguono, supponiamo di essere in una directory che contiene 4 files : myfile.txt , program.f , .login (hidden file) e tmp (una directory). Quest’ultima a sua volta, contenga un file di nome test . ls myfile.txt program.f tmp ls -a .login myfile.txt program.f ls -R myfile.txt program.f tmp tmp tmp: test nell’ultimo esempio, la lista include non solo il contenuto della current directory (esclusi gli hidden files) ma anche tutti i files di tutte le sottodirectories piu’ basse nella gerarchia delle 99* directories. ls -l total 1 -rwxr-xr-x 1 user1 GR1 1024 24 Aug 13:40 myfile -rwxrwx--x 1 user1 GR1 512 10 Jul 21:10 program.f drwxr-xr-x 2 user1 GR1 30 12 Sep 04:10 tmp il comando ls -l fa il long listing dando informazioni addizionali sul tipo di file (vedi dopo la sezione sulle caratteristiche di un file) ls * questo comando fa la lista della current directory piu’ dei files contenuti nelle directories UN livello piu’ in basso. In modo analogo, ls */* fa la lista dei files nella current directory e nelle directories UNO e DUE livelli piu’ in basso. ls -F myfile.txt program.f* tmp/ questo comando indica anche il tipo di file : * e’ un file che ha la protezione x (puo’ essere eseguito) , / indica che e’ una directory, @ significa un symbolic link mentre = significa che e’ un socket . ls -1 myfile.txt program.f 100* tmp ls -C questo comando forza il formato a multicolonne (che e’ comunque il default) ls -t questo comando elenca i files in ordine temporale tenendo conto della data di ultima modifica ( i files piu’ recenti vengono elencati prima ) ls -r elenca i files in ordine alfabetico inverso ls -rt elenca i files in ordine temporale inverso Ordine seguito nel produrre le liste A meno che non venga modificato da un’opzione, l’ordinamento dei files elencati e’ : 1) files che cominciano con un punto 2) files che cominciano con un numero 3) le maiuscole 4) le minuscole Esempio : 101* ls -a .123 .Test .test 123 Prova prova Combinazioni di piu’ opzioni Le opzioni di ls possono essere combinate tra loro, ad es. ls -a -l ( equivalente a ls -al ) produce una long list di tutti i files, anche gli hidden. Caratteristiche dei files Si consideri il seguente esempio : ls -l -rwxr--r-1 danny staff 1000 10 Aug 12:20 testfile questo e’ un full listing delle caratteristiche, che ora esamineremo, del file testfile 1) Il primo carattere e’ la descrizione del tipo di file : d directory file b block-type special file c character-type special file l symbolic link s socket file normale (ASCII o binario) 2) I 9 caratteri seguenti ( rwxr--r-- ) definiscono le protezioni del file per l’utente, il gruppo, tutti gli altri. In Unix e’ sottinteso che il system manager abbia tutti i privilegi. Protezione r significa possibilita’ di leggere il file, w di scrivere o cancellare,102* x di eseguire. 3) Il secondo campo nell’esempio, indica il numero di links che il file possiede ( 1 ) ; un file ha sempre almeno 1 link alla directory alla quale appartiene ; una directory ha sempre almeno 2 links, uno alla directory della quale e’ sottodirectory, un altro ai files contenuti in essa. Altri links possono essere definiti col comando ln 4) il terzo campo e’ l’owner del file 5) il quarto campo e’ il gruppo al quale l’owner appartiene ( e di conseguenza anche il file ) 6) segue poi la grandezza del file espressa in bytes 7) seguono quindi data di ultima modifica del file ( eventualmente data di creazione del file ) ed ora 8) nell’ultimo campo c’e’ il nome del file. 103* Comando umask Questo comando assegna il tipo di protezioni od accessi di default per la current shell, per tutti i files creati susseguentemente. Sintassi : umask [opzione] [value] Senza argomenti, mostra la file creation mask di default. Con l’argomento value la assegna. Mask e’ data come valore ottale. Bisogna tenere presente che la mask effettiva assegnata ad un nuovo file e’ mode & ~value dove mode e’ una maschera aggiuntiva data dal sistema, di solito 666 umask 022 assegna accesso 666 & ~ 022 = 644 vale a dire r , w per user e r access per group ed other ( tutti gli altri utenti ). 104* Current directory, cambio di directory Current directory Il comando che mostra la current directory e’ pwd pwd /home/boca Cambio di directory Sintassi : cd directory oppure chdir directory dove directory puo’ essere sia un relative directory path che un absolute directory path pwd /home/boca/dimostrazione cd ../cestino la nuova directory e’ /home/boca/cestino cd /home/boca la nuova directory e’ /home/boca cd senza argomenti, indica la home directory. Dopo questo comando, la directory e’ /home/boca 105* La C-shell estende l’uso di cd per mezzo della shell variable cdpath ; infatti se directory non e’ un sottodirettorio del current directory, e non incomincia per / , ./ oppure ../ , allora ciascun componente della shell variable cdpath viene controllato per vedere se ha come sottodirectory directory e se si’ tale sottodirectory diventa la current directory. Infine se anche questo fallisce, la C-shell controlla se directory non sia una shell variable il cui nome incomincia per / , ed in tal caso fa diventare tale nome la current directory (se esiste). set cdpath = /usr/test pwd /programs/new cd temp pwd /user/test/temp set cdpath = (/usr/doc /user/com) 106* Directory stack E’ una lista di directories definito dalla C-shell solo per la sessione corrente. La current directory e’ sempre in cima alla lista. L’utente puo’ costruire ed utilizzare il directory stack coi comandi pushd , popd , dirs Sintassi : pushd directoryname Azione mette in cima al directory stack la directory directoryname e fa : diventare directoryname la current directory Sintassi : dirs Azione mostra il directory stack : Sintassi : pushd +n Azione ruota lo stack n volte : Sintassi : popd Azione elimina il current directory dalla cima della stack, lasciando invariati : gli altri ; fa diventare il prossimo directory dello stack il current 107* directory pwd /user2/programs/new pushd /usr /usr /user2/programs/new pwd /usr dirs /usr /user2/programs/new pushd /etc /etc /usr /user2/programs/new pushd +1 /usr /user2/programs/new /etc pwd /usr popd /user2/programs/new /etc 108* Per ultimo si noti che il comando cd ( o chdir ) ha l’effetto sul directory stack di cambiare solo la directory in cima nel current directory, lasciando le altre directories della lista invariate dirs /user2/programs/new cd /etc /tmp dirs /tmp /etc 109* Creazione di directories Sintassi : mkdir [opzioni] directoryname Azione crea la nuova directory directoryname . Quest’ultimo puo’ essere sia un : pathname relativo ( alla current directory ) sia un pathname assoluto. pwd /user2/programs/new mkdir tmp pathname relativo ls /user2/programs/new/tmp pwd /user2/programs/new mkdir /user2/programs/new/test ls /user2/programs/new/tmp pathname assoluto 110* /user2/programs/new/test Rimozione di files e directories Sintassi : rm [opzioni] nomefile Azione rimuove nomefile ( dove quest’ultimo puo’ essere un pathname : assoluto o relativo ) -i -r Opzioni : l’opzione -i fa si’ che prima di rimuovere il file un messaggio appaia a terminale per chiedere conferma di voler cancellare il file l’opzione -r rimuove una directory con tutto il suo contenuto ( incluse eventuali altre directories con i loro contenuti ) ls file1 file2 pippo prova tmp.f rm file1 rm -i p* rm : remove pippo ? rm : remove prova ? In questo esempio l’uso dell’opzione i fa apparire il messaggio di conferma 111* al quale l’utente deve rispondere con un yes o y NOTA BENE Per poter rimuovere un file occorre che esso abbia la permission di tipo w (write e delete permission). Inoltre se la directory contenente il file non ha write access da parte dell’ owner allora compare il messaggio : Permission denied ed il comando non viene eseguito. ls -l -r--r--r-- 1 boca GR1 189 May 18 22;56 prova.f rm prova.f rm : override protection 444 for prova.f ? Il file prova.f ha permission di read only e quindi non viene cancellato. Il sistema chiede esplicitamente all’utente se vuole rimuovere il file , lo user deve rispondere con yes 112* o y per poter cancellare il file effettivamente. ls -l -r--r-xr-x 1 boca GR1 189 May 18 22:56 prova.f drwxr--r-- 1 boca GR1 512 May 19 13:14 cestino rm -r cestino Questo comando rimuove la directory cestino e tutto il suo contenuto 113* Copia di files e directories Sintassi : cp [opzioni] file1 Azione copia file1 su file2 . Se file2 esiste gia’, la vecchia versione viene : file2 sovrascritta Opzioni : -i -r L’opzione -i fa si’ che qualora file2 esista gia’, venga richiesta all’utente conferma prima di copiare. L’opzione -r serve per copiare directory intere ( con tutto il loro contenuto ). ls -1 file1 file2 cp -i file1 file2 overwrite file2 ? 114* ls -R pippo lista recursiva del contenuto della current directory pluto user1 user2 user1 e’ a sua volta una directory ./user1: program.f dati.dat user2 e’ a sua volta una directory ./user2: campo.FOR prog.c cp -r user1 user2 copia la directory user1 in user2 ls -R pippo pluto user1 user2 ./user1: program.f dati.dat ./user2: campo.FOR prog.c user1 ./user2/user1: program.f dati.dat in user2 c’e’ anche user1 con tutto il suo contenuto 115* Cambiare nome ad un file Sintassi : mv [opzioni] file1 file2 Azione muove files da una directory ad un’altra ovvero cambia nome a files e : directories Opzioni : -i -f -- L’opzione -i , come gia’ visto per il comando cp , fa si’ che qualora file2 esista gia’, venga richiesta all’utente conferma prima di sovrascriverlo. L’opzione -f al contrario, forza la sovrascrittura di file2 qualora esista gia’, cancellando l’effetto di un’eventuale opzione -i precedentamente definita ( con un alias ad es. ) L’opzione -- fa si’ che tutti gli argomenti del mv che seguono vengano interpretati come filenames. Questo permette ai filenames di cominciare con un - 116* ls file1 file2 mv -i file1 file2 overwrite file2 ? y ls file2 ls file1 file2 mv -- file1 -pinco l’opzione -- permette di dare a file1 un nome che comincia con - ls file2 -pinco 117* Display di un file I comandi piu’ usati per mostrare il contenuto di un file sono : cat , more ( o page ) , head , tail , pr , od Comando cat Sintassi : cat [opzioni] filename(s) Azione stampa a terminale il contenuto del file filename(s) facendo : automaticamente lo scroll del terminale. Opzioni : -n L’opzione -n fa il display del file numerando ciascuna linea in modo progressivo. 118* Comando more ( o page ) I comandi more e page sono equivalenti. Sintassi : more [opzioni] filename(s) Azioni mostra il contenuto del file filename(s) una pagina alla volta, per : default sono 2 linee in meno (22) di quante ne puo’ mostrare il terminale Opzioni : tra le molte opzioni, citiamo solo -number che fa il display con number linee, e +number che comincia il display a partire dalla linea number. Questi comandi mostrano una pagina alla volta, indicano la percentuale di file gia’ mostrata ed attendono il responso dell’utente. Battendo <cr> verra’ mostrata una linea in piu’, mentre battendo la barra dello spazio, viene mostrata la nuova paginata. NOTA BENE Questi comandi hanno alcune delle possibilita’ dell’editor vi , come ad es. la possibilita’ di andare avanti con f e tornare indietro con b , quella di pattern matching etc. assomigliando quindi molto ad un line editor read only. Per avere l’elenco completo di 119* queste possibilita’ basta battere h dopo aver attivato il comando more . Comando head Sintassi : head [opzioni] file(s) Azione fa il display della prima parte di file(s) : Opzioni : -number che fa il display delle prime number linee. Per default vengono mostrate le prime 10 linee Comando tail Sintassi : tail [opzioni] file(s) Azione fa il display dell’ultima parte di file(s) : Opzioni : -number che fa il display delle ultime number linee. Per default vengono mostrate le ultime 10 linee 120* cat file linea1 linea2 linea3 linea4 head -3 file | tail -1 linea3 121* Comando pr Sintassi : pr [opzioni] Azione stampa un file allo standard output, con vari formattamenti. Se il file da : file(s) stampare non viene specificato, o e’ un - , il comando prende input da standard input. Opzioni : citiamo solo le opzioni -number e -m Senza opzioni, pr stampa file(s) a pagine di 66 linee ciascuna aggiungendo per ogni pagina, nome del file stampato, data e numero di pagina, ed uno header ed un trailer di 5 righe vuote. Con l’opzione -number file(s) viene stampato in number colonne. Con l’opzione -m e nella forma pr -m file1 file2 vengono stampati file1 e file2 uno accanto all’altro ( utile per fare confronti di files ). E’ da notare che per default pr tronca le linee troppo lunghe. 122* Comando od Sintassi : od [opzioni] file(s) Azione stampa il contenuto ( dump ) a terminale di file(s) in formato ottale, : decimale, esadeciamale, ASCII Opzioni : dipendono da macchina a macchina, per OSF1 citiamo -o -O -a -h -H -i -I L’opzione -o ( default ) stampa il file in short words ( parole da 16 bits ) stampando il contenuto in ottale. L’opzione -O fa lo stesso, ma stampa il file in long words ( 32 bits ). L’opzione -a stampa file(s) a bytes, e rappresentando ciascun byte col carattere ASCII corrispondente. Le opzioni -h e -H stampano in esadecimale, il file suddiviso rispettivamente in short e long words. Infine -i e -I stampano short e long words interpretate come interi ( senza segno ). 123* cat file line1 od -a file 0000000 l i n e 1 nl 0000006 od -o la colonna piu’ a sinistra e’ un numero ottale che esprime il numero di bytes finora stampati file 0000000 064554 062556 005061 0000006 od -h 0000006 file 696c 656e 0a31 124* Cambio di protezione di files e directories Come gia’ detto, ogni file e directory ha 3 tipi di protezioni od accessi ( r , w , x ) per 3 tipi di utenti ( owner , group , all ) mentre il superuser ( system manager ) ha sempre tutti gli accessi disponibili. Il comando chmod permette all’utente owner di un file o directory di cambiare queste protezioni , mentre umask assegna le protezioni di default per la current shell. Sintassi : chmod [opzioni] mode file(s) Il livello di protezione (mode) puo’ essere dato in 2 modi, in forma assoluta od in forma simbolica. user group world ( other ) rwx rwx rwx 421 421 421 da cui 7 = 4+2+1 read, write , execute access 6 = 4+2 read, write 5 = 4+1 read, execute 4 = 4 read only 3 = 2+1 write , execute 2 = 2 write only 1 = 1 execute only 125* ls -l a.dat -r-x------ 1 chmod 755 a.dat ls -l boca GR1 1954 May 3 18:31 a.dat forma assoluta, codice ottale a.dat -rwxr-xr-x 1 chmod u-w,g+w,o=r ls -l a.dat -r-xrwxr-- 1 chmod a=rx a.dat ls -l a.dat -r-xr-xr-x 1 boca GR1 1954 a.dat May 3 18:31 a.dat forma simbolica boca GR1 1954 May 3 18:31 a.dat boca GR1 1954 May 3 18:31 a.dat 126* Cambio di proprieta’ di gruppo di files e directories Il comando chgrp cambia la proprieta’ di gruppo ( lo user titolare del file rimane lo stesso) di files e directories. Per applicare questo comando, chi lo fa deve essere il proprietario del file e deve appartenere al gruppo che riceve la proprieta’ del file. Sintassi : chgrp [opzioni] newgroup groups ; admin ls -lg file projecta -rw-rw-r-chgrp file admin -rw-rw-r-- 2 system file 2 ; system projecta ls -lg 1594 Feb 20 13:55 file 1594 Feb 20 13:55 file file admin 127* Confronto tra files In Unix si possono usare i comandi cmp e diff per stampare a terminale le differenze che esistono tra due files. Il comando cmp riporta solo la prima differenza trovata, e funziona anche con files non ASCII. Il comando diff riporta tutte le differenze tra due ASCII files. Sintassi : cmp [opzioni] file1 file2 diff [opzioni] file1 file2 pr -m file1 file2 Maine Texas Montana Montana Nebraska Illinois Illinois Alabama Iowa Maine cmp file1 file1 file2 file2 differ: char 1 line 1 128* si considerino gli stessi files precedenti. diff file1 file2 1c1 <Maine -->Texas 3d2 <Nebraska 5c4,5 <Iowa --- >Alabama >Maine 129* Il significato delle linee di output e’ il seguente : linea 1 : consiste di 3 campi a) n. della linea o range dei n. delle linee nel primo file, prima del cambiamento b) un carattere che descrive il tipo di cambiamento : a =append, c=change , d=delete c) il n. della linea od il range dei n. delle linee dopo il cambiamento linea 2 : le linea ( linee ) dal primo file, nel caso sia appropriato, identificate con < linea 3 : se necessario, il delimitatore --- tra gli items del primo e del secondo file linea 4 : se necessario, le linee del secondo file, identificate con > Nell’ esempio quindi, il significato dell’output e’ : cambiare Maine in Texas in file1 , la linea n. 1 rimane la linea n. 1. Cancellare la linea n. 3 ( Nebraska ) dal file1 cosi’ che la linea 3 diventa la linea 2. Cambiare la linea 5 in file1 da Iowa in due nuove linee, Alabama e Maine, cosi’ che la linea 5 diventa linea 4 e linea 5. diff -e L’opzione file1 file2 -e produce in output i comandi da dare all’editor ed per far diventare file1 identico a file2 130* diff -r dir1 dir2 L’opzione -r permette confronti fra le directories dir1 e dir2 , riportando o l’esistenza di un file in una sola delle directories o le differenze tra files che hanno lo stesso nome ; questo tipo di confronto viene ripetuto per tutte le sottodirectories di dir1 e dir2 . 131* Ricerca di files Si usa il comando find per cercare un file che si trova in una certa directory od in una sua qualunque sottodirectory che si trovi piu’ in basso nella gerarchia delle directories. ls -R visto in precedenza. Questo comando offre piu’ funzionalita’ di Con find si possono usare vari criteri per localizzare il file(s), si possono manipolare il file(s) trovati oppure eseguire comandi se si e’ localizzato il file(s). Le ampie funzionalita’ di find richiedono pero’ una sintassi piu’ complicata dei comandi fin qui visti ; tra l’altro le varie opzioni devono venir date nel seguente ordine ( a differenza della maggioranza degli altri comandi della C-shell ) Sintassi : find pathname criterion action pathname : directory di partenza da cui iniziare la ricerca criterion : criterio da usare nella ricerca del file(s) ad es. il nome del file(s) action : quello che il sistema deve fare una volta trovato il file(s) find / -name ourfile /user1/bin/ourfile /user3/progs/ourfile -print 132* find / -name myfile -exec file {} \; /user1/bin/myfile: executable /usr/local/myfile: directory /etc/myfile: empty /user3/myfile: ascii text /user4/data/myfile: data /user5/scripts/myfile: commands text trova a partire da / i files di nome myfile e per ognuno di essi esegue il comando file . Si noti l’uso delle parentesi { } e di \; obbligatorio quando si usa l’opzione -exec . find /user1 -mtime +45 -print trova i files con modification time maggiore di 45 giorni e stampali a terminale. Da notare che qui modificato significa scritto. find /user1 -name ‘*.f’ -atime -45 -print .f trova i files che terminano con e che hanno access time ( cioe’ l’ultima volta che sono stati letti ) minore di 45 giorni. find /usr -name ‘*.f’ \( -mtime -3 -o -atime -6 \) -exec rm {} \; trova, a partire da /usr i files che terminano con .f scritti da meno di 3 giorni 133* OPPURE ( OR logico, opzione -o ) letti da meno di 6 giorni, e cancellali ( -exec rm {} ) Ricerca del contenuto di files Il comando grep cerca una determinata stringa di caratteri in uno o piu’ files. Sintassi : grep [option(s)] pattern file(s) cat file George says : hey, hello there, what a nice day! And Ann answers : who cares ? grep ‘hello there’ file hey, hello there, what a nice day! grep -i ‘HELLO there’ file*.txt -i : ricerca case insensitive file1.txt: hey, hello there, what a nice day! file2 txt: hey, hello there, what a horrible day! grep -n Goodbye file3 -n : n. della linea(e) che ha la stringa cercata 12:Goodbye and have a nice day! grep -c Goodbye file3 1 -c : n. di linee che hanno la stringa cercata 134* grep -v hey file -v : display delle linee che NON corrispondono George says : And Ann answers : who cares ? grep -l hey fil* -l : mostra solo il nome del file (1 volta sola) nel quale una o piu’ corrispondenze sono state trovate file grep -e hello -e George file -e : opzione che serve per cercare uno o piu’ patterns George says : hey, hello there, what a nice day! Per cercare uno o piu’ patterns e’ possibile usare l’opzione -f ed un file di testo. In tal caso ciascuna linea del testo diventa la stringa di caratteri con cui fare il confronto. cat match hello George grep -f match file George says : 135* day! hey, hello there, what a nice Con grep e’ possibile usare le cosiddette regular expressions che sono stringhe composte di normali caratteri e metacaratteri, che sono un potente mezzo per specificare i patterns con cui cercare in un file. Le regole per formare regular expressions sono molto articolate, si possono trovare ad es. con man grep , qui daremo solo un paio di esempi. grep mode$ file ricerca del pattern mode posto alla fine della linea grep ^the ricerca del pattern the posto all’inizio di una linea file ls -l | grep ^d ricerca delle sottodirectories contenute nella current directory 136* Sort e merge di files In Unix viene usato il comando sort per ordinare ( sorting ) alfabeticamente un file di testo e/o per congiungere ( merging ) piu’ files in un unico file. Sintassi : sort [option(s)] [+pos1] [-pos2] file(s) cat file1 aaaaa 123 Abbb zzzzzz sort file1 sorting nello stesso ordine usato da ls 123 l’output e’ lo standard output Abbb aaaaa zzzzzz 137* cat file2 Boca gianluigi sort file1 file2 ordina file1 e file2, considerandoli come un unico file, 123 e produce un unico output ( merging ) che va a stdout Abbb Boca aaaaa gianluigi zzzzzz 138* sort -o out file1 output va al file out (uguale a sort file1 > out ) sort -f file1 file2 non fa distinzione tra maiuscole e minuscole 123 al momento del sorting aaaaa Abbb Boca gianluigi zzzzzz cat prova sedd 123 456 abc ase 19 25 cccc xdrf aaa 343 20 arrt eee sort -k 4,6 prova sedd 123 456 abc sceglie il sort key field il quarto campo e, nel caso di uguaglianza, il 5o ed il 6o. Se sono ancora uguali, si cons aaa 343 20 arrt eee tutta la riga. I campi vengono definiti dal delimitatore di ase 19 25 cccc xdrf default che e’ il blank ; un campo (in assenza dell’opzione 139* -t ) e’ definito come una sequenza massimale di non-blanks piu’ tutti i blanks che precedon sort -k 2n,2n prova il sort key field e’ il secondo campo, e’ ase 19 25 cccc xdrf numerico e l’ordinamento considera l’intero sedd 123 456 abc numero che c’e’ nella sort key ( opzione n ) aaa 343 20 arrt eee cat prova sedd:123:456:abc ase:19:25:cccc:xdrf aaa:343:20:arrt:eee sort -t: -k 2n,2n prova come il sort precedente, ma i campi ora ase:19:25:cccc:xdrf sono delimitati da : (opzione -t ); inoltre sedd:123:456:abc con questa opzione ogni delimitatore diventa aaa:343:20:arrt:eee significativo nel senso che due delimitatori consecutivi definiscono un campo vuoto. 140* cat prova sedd:123:456:abc sedd:123:46:abc ase:19:25:cccc:xdrf aaa:343:20:arrt:eee sort -t: -k 2n,2n -k 3n,3n prova esempio di multifield sort key. ase:19:25:cccc:xdrf Prima il confronto avviene con il sort key field sedd:123:46:abc n. 2, in caso di uguaglianza si passa al prossimo sedd:123:456:abc sort key field, che e’ il n. 3 ; entrambi sono aaa:343:20:arrt:eee numerici. Il delimitatore e’ : sort -t: +1n -3 esempio di sort field dato con + - prova ase:19:25:cccc:xdrf Il confronto avviene con il sort key field n. 1 numerico (1n) sedd:123:46:abc e termina col campo 2 (che viene prima del campo 3). Si sedd:123:456:abc noti che con questa opzione i campi si contano 141* a partire da aaa:343:20:arrt:eee 0. Creazione od updating di un file : comando touch Il comando touch aggiorna la modification date di un file ( data dell’ultima volta in cui il file fu scritto ) se esiste gia’, oppure crea un file vuoto se esso non esisteva ancora. Sintassi : ls -l touch [option(s)] file a.out -rwxr-xr-x 1 boca GR1 24576 May 2 17:29 a.out 19:01 a.out 142* ultima modification time touch a.out ls -l a.out -rwxr-xr-x 1 boca GR1 24576 May 25 nuova modification time ls a.out b.out prova.f touch pippo ; ls a.out b.out pippo b.out prova.f prova.f crea il file ( vuoto ) pippo ls a.out touch -c pippo a.out b.out ; ls prova.f l’opzione -c impedisce la creazione del file pippo 143* Character translator Il comando tr copia caratteri dallo stdin allo stdout con sostituzione o cancellazione dei caratteri selezionati dall’utente. Sintassi : tr [option(s)] char1 char2 char1 e’ il carattere che viene sostituito con char2 tr A a < file1 > file2 trasforma tutte le A maiuscole presenti in file1 in a minuscole, e mette l’output in file2. tr A-Z a-z < file1 > file2 trasforma tutte le maiuscole presenti in file1 in minuscole, e mette l’output in file2. tr -d A < file1 > file2 cancella tutte le A maiuscole presenti in file1 e mette l’output in file2. 144* Word counting Il comando wc conta il numero di linee, parole, caratteri ( o bytes ) presenti in uno o piu’ file di testo ASCII e li scrive allo stdout. Nel caso di piu’ files in input ne stampa anche il totale. wc [option(s)] file(s) Sintassi : cat testo sedd 123 456 abc ase 19 25 accc xdrf aaa 343 20 arrt eee wc testo 3 14 57 testo 12 21 189 prova.f 4 7 47 prova1.f wc prov* 16 28 236 total 145* Link tra files Un link e’ un nome diverso dato ad un file gia’ esistente. Un link non e’ una copia separata dello stesso file, ma solo una directory entry in piu’ che conduce allo stesso file. Dato che un file puo’ avere multipli links, puo’ succedere che users diversi leggano o scrivano contemporaneamente lo stesso file e si possono percio’ avere problemi di corruzione di files. Ci sono due tipi di links : un hard link ( default ) ed uno soft o symbolic link. Lo hard link crea una nuova directory entry per il medesimo file ( senza duplicarlo fisicamente ) cosi’ che lo stesso file fisico e’ accessibile con due ( o piu’ ) nomi diversi. Se l’utente cancellasse il file originario ( nome vecchio ) il file sarebbe accessibile allo stesso modo col nome nuovo e finche’ anche il nome nuovo non e’ cancellato, il file non scompare dalla memoria. Quando l’utente crea uno hard link il link count aumenta di uno, ma l’ inode del file e’ identico a quello vecchio. Uno hard link non puo’ abbracciare filesystems diversi.146* Un symbolic link invece e’ solo un file che contiene il path per il file originale. Se il file originario fosse cancellato, il link continuerebbe ad esistere, ma non ci sarebbe piu’ modo di accedere all’informazione del file originario. Un link simbolico non incrementa il link count. Un link simbolico puo’ abbracciare filesystems diversi. 147* Sintassi : ln [option(s)] name1 name2 dove name1 e’ il nome del file che esiste gia’ mentre name2 e’ il nome del nuovo file, link del vecchio. ls -li 1035465 -rw rw r-- 1 system 2046 ln file1.dat foo Feb 25 13:58 file1.dat hard link ls -il 1035465 -rw rw r-- 2 system 2046 Feb 25 13:58 file1.dat 1035465 -rw rw r-- 2 system 2046 Feb 25 13:58 foo 1 system 2046 Feb 25 13:58 file ls -li 1035465 -rw rw r-ln -s file foo link simbolico ls -il 1035465 -rw rw r-- 1 system 2046 Feb 25 13:58 file 1024567 lrw rw r-- 1 system 2046 Feb 25 13:58 foo 148* -> file Questo capitolo tratta di quei comandi che permettono di : monitorare gli users ed i loro process whoami users (u) who w rwho ps top du limit displays the users’s name monitorare il sistema displays virtual memory statistics displays statistics on free disk space vmstat df displays a list of users who are on the system identifies users currently logged in modifica dei process summary of current system activities shows users logged in to hosts on the local network kill send a signal to a process shows current process status at runs commands at a later time crontab display and update information nice submits a schedule of about the top cpu processes renice commands to cron displays a summary of disk usage lists the system resources available to user lowers priority to a process to be executed 149* or reduces resources limits of a process alters priority to running processes 7.1 Monitorare gli users ed i loro process Esaminiamo ora quei comandi che permettono di sapere quanti e quali utenti sono collegati al sistema, quali process hanno ‘lanciato’, quanto spazio su disco e’ ancora disponibile, quali sono i limiti di utilizzo delle risorse del computer imposti ad un certo utente. Comando whoami Sintassi : whoami Azione mostra lo username associato : con la sessione corrente. Serve per esempio quando si utilizzano piu’ sessioni contemporaneamente se ci si dimentica con quale username abbiamo aperto la sessione. 150* Comandi users ( u ), who, w e rwho Questi comandi forniscono informazioni, via via con maggiore dettaglio, sugli utenti correntemente collegati in modo interattivo. Sintassi : users (oppure u ) Azione stampa a terminale l’elenco alfabetico degli usernames degli utenti : interattivi che sono correntemente collegati usernames degli utenti correntemente collegati in interattivo 151* Sintassi : who Azione stampa a terminale l’elenco degli usernames degli utenti : interattivi che sono correntemente collegati, il nome del device al quale il terminale dell’utente e’ collegato, e l’ora del login. device username login time 152* Sintassi : w [option(s)] [username] Azione stampa a terminale una linea di header con l’ora corrente, da quanto : tempo il computer e’ attivo, il numero di utenti, ed il load average, vale a dire il numero di jobs nella run queue negli ultimi 5 secondi, 30 secondi o 60 secondi. Di ciascun utente (se username manca) od eventualmente solo dell’utente username viene mostrato : username, device, da quale computer e’ stato fatto il login, ora del login, da quanto tempo l’utente e’ rimasto idle, il CPU time accumulato da tutti i process dell’utente dal momento del login (JCPU) in minuti, il CPU time (in minuti) usato da(i) process(es) attivi correntemente (PCPU), il nome del programma eseguito dal current process. 153* Sintassi : w [option(s)] [username] Azione stampa a terminale una linea di header con l’ora corrente, da quanto : tempo il computer e’ attivo, il numero di utenti, ed il load average, vale a dire il numero di jobs nella run queue negli ultimi 5 secondi, 30 secondi o 60 secondi. Di ciascun utente (se username manca) od eventualmente solo dell’utente username viene mostrato : username, device, da quale computer e’ stato fatto il login, ora del login, da quanto tempo l’utente e’ rimasto idle, il CPU time accumulato da tutti i process dell’utente dal momento del login (JCPU) in minuti, il CPU time (in minuti) usato da(i) process(es) attivi correntemente (PCPU), il nome del programma eseguito dal current process. 154* Sintassi : rwho [-a] [username] Azione comando che fornisce informazioni analogomente al comando who, : ma anche per users collegati su computers remoti facenti parte del network locale. Se username viene specificato, solo su di esso vengono date informazioni Opzioni : -a per elencare tutti gli utenti sui computer remoti; altrimenti sono segnalati solo quelli che hanno toccato la tastiera nell’ultima ora. username hostname device login time idle time (in minuti) 155* Comando ps Questo comando (process status) mostra le risorse del sistema che vengono ‘consumate’ da uno o piu’ process. Sintassi : ps [option(s)] Azione stampa a terminale un elenco di risorse usate da uno o piu’ process : Opzioni : ci sono molte opzioni, molte sono machine-dependent; qui di seguito sono esemplificate le principali, valide per Linux. Per maggior dettagli : man ps comando impartito process ID number terminale da cui e’ stato lanciato il process CPU time usato dal process 156* Sintassi : ps -l Azione come ps ma con maggiori dettagli (long list) : status of process : R = running ; S = sleeping ; D = uninterruptible sleep (IO queues) Z = zombie (stoppato in modo non appropriato dal parent process) ; T = stopped ; W = swapped out ; C = negative nice values ; N = positive nice values user ID number parent process ID number % CPU used address of the name of the kernel function the task currently is sleeping in priorità (valori piu’ alti = minore priorita’) nice value = process scheduling increment; (valori piu’ alti = minore priorita’) 157* Sintassi : ps -f Azione come ps ma con maggiori dettagli (full list) : start time of the process 158* Sintassi : ps -v Azione come ps ma con maggiori dettagli; mostra lo stato della memoria : virtuale percentage of physical memory used by the job status of process total amount of physical memory used by the task in Kbytes 159* Sintassi : ps -u username Azione mostra informazioni su tutti i process appartenenti a username, : anche quelli che non sono stati lanciati dalla sessione corrente. job lanciato non dalla sessione corrente e non ‘attaccato’ ad alcun terminale job lanciato dalla sessione corrente ed attaccato al suo terminale 160* Sintassi : ps -e Azione mostra informazioni su tutti i process presenti sul computer : con anche opzione f 161* Riassunto delle opzioni disponibil i con ps su Linux 162* Comando top Questo comando mostra l’attivita’ del processore in real time. Mostra una lista dei jobs maggiormente CPU-intensive del sistema e fornisce un’interfaccia interattiva per manipolare i process. Sintassi : top [option(s)] Azione produce una schermata che viene rinfrescata di default ogni 5 secondi : con informazioni sui process maggiormente CPU-intensive. Opzioni : [-d delay specifica che il display venga rinfrescato ogni delay secondi [-p ID viene mostrato solo il process con ID number ID [-q viene rinfrescato il display il piu’ velocemente possibile [-n num viene rifrescato il display num volte e poi top finisce. 163* % CPU usata dagli utenti numero e tipo di jobs % CPU usata dal sistema % jobs con NICE negativa % jobs idle stato memoria del sistema stato swap space size of the job code + data + stack, in Kbytes total physical memory used by job, in Kbytes total shared memory status, < for processes with negative nice, W for swapped processes (doesn’t work correctly for kernel processes) 164* Comando du Sintassi : Azione : du [option(s)] [file(s)] [directory(ies)] segnala quanto spazio su disco e’ occupato dai files o directories specificate (in unita’ di 1024 bytes 1 Kbyte) e per ciascuna subdirectory. Opzioni : -a se l’argomento e’ una directory mostra lo spazio occupato da ciascun file, non solo dalla directory -s summary, fa vedere lo spazio occupato in totale da ciascun argomento. 165* equivalente a du . dimensioni in Kbytes directory 166* Comando limit Sintassi : Azione : limit [resource] [value] e’ un commando built-in nella C shell. Elenca le risorse di sistema disponibili ai process di un utente. Si puo’ usare questo comando per diminuire (non per aumentare !) i valori assegnati, specificando resource e value. maximum CPU time assigned maximum size in Kbytes of any one file maximum size in Kbytes of the core dump file amount of maximum memory (in Kbytes) a user can consume maximum processes at the same time maximum number open files at the same time 167* pone a zero la massima grandezza possibile del file core (cioe’ in pratica impedisce la creazione di core ). 168* 7.2 Monitorare il sistema Esaminiamo ora dei comandi che permettono di sapere come l’insieme di tutti gli utenti usa le risorse di memoria virtuale e di memoria su disco ( comandi vmstat e df ). Comando vmstat Sintassi : vmstat [option(s)] [delay [count]] Azione mostra la statistica della memoria virtuale del sistema, fornendo : anche informazioni sui process, su paging, block IO, traps ed attivita’ della CPU. Il primo output del comando fa una media a partire dall’ultimo reboot del sistema, successivamente, se delay e’ stato specificato, le varie quantita’ vengono calcolate ogni delay secondi, per count volte. Se delay e’ stato specificato ma count no, il display viene fatto fino ad interruzione del comando con <ctrlC>. Opzioni : -n lo header dell’output del comando viene fatto vedere una volta sola. 169* process status r : n. waiting for run time b : n. in uninterruptible sleep w : n. runnable but swapped out memory (in Kb) virtual memory used free memory memory used as buffers amount of cache 170* swap space si : memory swapped in from disk (Kb/s) so : memory swapped out to disk (Kb/s) ogni 10 secondi, per 5 volte system in : n. interrupts per sec. cs : number of context switch per sec. us : % user CPU time sy : % system CPU time I/O bi : blocks sent to a block device (blocks/s) bo : blocks received from a block device (blocks/s) 171* Comando df Sintassi : df [options] [file(s),directory(ies)] Azione mostra lo spazio su disco usato e disponibile. Senza argomenti, mostra la : quantita’ di spazio per tutti i file systems montati sulla macchina. Con argomento file(s) o directory(ies) lista lo spazio disponibile ed usato del filesystem al quale il file o la directory appartiene. Opzioni : -a all, lista anche i filesystems che hanno dimensione 0 --block-size=SIZE usa come unita’ di misura blocchi da SIZE-byte -k usa come unita’ di misura blocchi da 1024 bytes -i lista l’informazione sugli inodes al posto della dimensioni in blocchi. 172* filesystems spazio totale disponibile in Kb spazio usato (Kb) spazio disponibile (Kb) % spazio usato mount point viene mostrato lo spazio su disco disponibile ed usato del filesystem al quale la directory /home/boca appartiene 173* 7.3 Modifica dei process Unix possiede 5 comandi usati comunemente per modificare i process degli utenti : kill , per terminare un process; at , per far partire un process piu’ tardi; crontab , per schedulare la partenza periodica di jobs, nice per modificare la priorita’ che il systema assegna di default ad un process che parte; renice per modificare la priorita’ di un process gia’ lanciato e limit , che abbiamo gia’ visto, per ridurre le risorse disponibili ad un process. Comando kill Sintassi : kill [options] [-s signal] [PID] [%jobnumber] Azione comando built-in nella C shell. Manda il signal specificato al process : specificato da PID o da %jobnumber . Opzioni : segnalo l’opzione -9 per far terminare certamente un process. 174* jobnumber process identification number (PID) opzione -9 per eliminare certamente il process 175* Comando at Sintassi : at [options] time command ... command <ctrlD> Azione : esegue uno o piu’ comandi all’istante specificato da time . La lista dei comandi da eseguire deve essere messa nelle linee che seguono at [options] time e deve essere terminata da un <ctrlD>. L’eventuale output dei comandi che normalmente verrebbe mandato a stdout , viene invece spedito per mail all’utente. La data puo’ essere specificata (in LINUX) in vari modi, vedi man at per la lista completa delle possibilita’. Nel seguito vengono mostrati solo alcuni esempi. 176* ora alla quale il comando verra’ eseguito 177* data alla quale il comando verra’ eseguito 178* comando da eseguire 179* il <ctrl>D finale per segnalare che l’input di at e’ finito 180* ora alla quale il comando verra’ eseguito, in questo caso alle 16:00 (altri modi ammessi sono : noon , midnight ) 181* Comando crontab Sintassi : crontab [options] Azione questo comando edita, lista o rimuove la tabella usata da cron, che e’ : un programma daemon che permette di far partire programmi o comandi in maniera automatica e periodica. Come at fa partire jobs automaticamente, tuttavia li fa partire periodicamente, ad una data ora di determinati giorni di determinati mesi dell’anno. Il programma cron legge la tabella nella quale sono elencati i jobs da far partire, ad ogni quanto tempo. Opzioni : -l mostra la tabella usata da cron -e edita la tabella usata da cron con l’editor di default -r cancella la tabella usata da cron 182* opzione -l : lista la tabella usata da cron il giorno del mese (da 1 a 31) in cui deve partire il job il minuto (da 0 a 59) in cui deve partire il job l’ora (da 0 a 23) in cui deve partire il job NOTA BENE valori accettati nei campi numerici : - un intero - una lista di interi separati da virgole - due interi separati da - per indicare un range - un * per indicare tutti i valori possibili 183* il mese dell’anno (da 1 a 12) in cui deve partire il job (* = ogni mese) NOTA BENE si possono specificare i giorni in cui far partire il job in due campi (giorno del mese e giorno della settimana). Si possono usare sia entrambi i campi, che un campo solo. Se si usa solo un campo, l’altro deve avere l’asterisco. nome del job da far partire il giorno della settimana in cui deve partire il job (* = ogni giorno) 184* Comandi nice e renice Sintassi : nice number [command] Azione questo comando fa partire il nuovo job command con scheduling : priority modificata aggiungendo number alla priorita’ normalmente assegnata di default dal sistema. La priorita’ aggiuntiva va da -20 (il job viene eseguito piu’ in fretta) a 19 (esecuzione piu’ lenta). Tuttavia solo il superuser puo’ assegnare un nice negativo. Opzioni : -ADJUST priorita’ aggiuntiva; il normale utente puo’ usare solo un valore positivo. Sintassi : renice number [PID] [-g [pgrp]] [-u [user] ] Azione altera la scheduling priority di uno o piu’ jobs che runnano. Per la : priority vale lo stesso discorso fatto per nice. Specificando PID si altera il nice di un job, specificando -g pgrp si alterano le priorita’ di tutti i process di quel gruppo, specificando -u user si alterano tutti quelli di quell’utente. 185* fa partire il job in normalmente e lo mette in background Process ID number priorita’ del job fa partire il job con nice positiva e lo mette in background Process ID number 186* priorita’ del job nice del job modifica il nice del job 974 che gia’ runna 187* Questo capitolo tratta della programmazione mediante comandi di shell, raggruppati in in costrutti in un file chiamato shell script . Discuteremo solo la sintassi della C (tcsh) shell. 188* 8.1 Esecuzione di un shell script E’ sufficiente scrivere a terminale il nome dello script. Se tale nome e’ dato in forma relativa, la C shell usera’ la variabile di shell path per sapere in quali directories cercare lo script. Lo script dovra’ avere la protezione x on per poter essere eseguibile. directories nelle quali viene cercato lo script unica eccezione : NON e’ una Come tutti i comandi che non sono built-in linea di commento ma la nella shell, lo script viene eseguito da un dichiarazione che il testo che child process con un forking al momento segue deve essere interpretato dal dell’esecuzione del comando. Il child process programma /bin/tcsh (la tc shell) eredita tutte le variabili di shell definite per il #!/bin/tcsh -f parent process. In piu’ per esso viene eseguito #questa e’ una linea di commento exit il file .cshrc (e .tcshrc) e quindi eredita tutte il # serve per commentare le definizioni ivi contenute. Quest’ultima 189* cosa viene evitata con l’opzione -f (fast start) e far partire lo script piu’ velocemente 8.2 Variabili di shell Sono gia’ state definite le variabili di shell precedentemente ed e’ gia’ stato detto che ad esse si possono assegnare valori tramite il comando set. Riassumiamo qui alcuni concetti: le variabili di shell sono valide solo per il process per il quale vengono assegnate e per tutta la durata di quest’ultimo. Vengono perse quando si cambia shell. ad una variabile di shell si possono assegnare sia numeri che caratteri il contenuto di una variabile di shell si ottiene facendo precedere il nome della variabile dal metacarattere $ valore numerico ci si e’ dimenticati del $ !! valore alfanumerico 190* Variabili di shell preassegnate il comando set senza argomenti ci da’ la lista delle variabili di shell preassegnate e di quelle definite dall’utente nome della variabile di shell contenuto della variabile di shell 191* Forme speciali di una variabili di shell La tavola qui sotto riporta le forme speciali che puo’ assumere una variabile di shell che, tra l’altro, puo’ contenere piu’ valori, come un vettore. In questo caso (a differenza del C) gli elementi del vettore vengono contati a partire da 1. Tavola 0 se la variabile name non e’ definita, 1 se e’ definita numero di elementi della variabile name da’ l’elemento m -esimo della variabile da’ gli elementi da m a n compresi della variabile name da’ gli elementi da m (compreso) fino all’ultimo della variabile name $name[-m] da’ gli elementi dal primo fino al m-esimo compresi della variabile name $name[*] da’ tutti gli elementi della variabile name $name[$#name] l’ultimo elemento della variabile name $?name $#name $name[m] $name[m-n] $name[m-] 192* Forme speciali di una variabili di shell assegnazione di 8 valori alla variabile di shell var che cosi’ diventa un vettore. Si notino le ( ) , obbligatorie. la variabile var e’ stata definita la variabile var e’ un array di 8 valori dal secondo al sesto valore della variabile var dal terzo all’ultimo valore della variabile var tutti i valori della variabile var ultimo valore contenuto nella variabile var 193* Comando shift Shift opera sulle variabili di shell riducendone il numero di elementi di uno, scartandone ogni volta il primo elemento. Sintassi : shift variable #!/bin/tcsh set z = ( uno due 3 ) echo “Before using shift there are $#z elements :$z” while ($#z>0) echo $z[1] shift z end echo “After using shift there are $#z elements” exit 194* Passare variabili ad uno script Nella tavola qui sotto vengono indicate i nomi della varibili che possono essere passate al runtime, piu’ altre utili variabili di shell. Negli esempi ne viene illustrato un possibile uso. Tavola $n o $argv[n] $* da’ il valore della n-esima variabile passata allo script da’ il valore di tutte le variabili passate allo script $$ $< $0 $?0 da’ il process number (PID) della shell corrente accetta input dal terminale variabile contenente il nome dello script che viene eseguito da’ 0 se il nome dello script che viene eseguito e’ conosciuto, 1 altrimenti 195* Passare variabili ad uno script continuazione del #!/bin/tcsh commento alla # returns variable passed \ prossima riga to script echo $argv[1] echo $2 echo $argv[$#argv] echo -n “Enter Text String:” set name = $< echo “This script is called $0” argomenti passati echo “This script is being processed by PID $$” a test_script3 echo “The string entered has $#name elements” echo “The first word is $name[1]” echo “The last word is $name[$#name]” exit input dato da terminale si notino le parentesi tonde, obbligatorie per poter far diventare name un vettore 196* 8.3 Filename modifiers I filename modifiers fanno si che il sistema ritorni porzioni di un filename relativo od assoluto, come esemplificato dalla tabella qui sotto, e dallo script test_script4. Tavola :r :e :h :t da’ la parte del filename che precede il . , se non contiene il . , ritorna il nome completo da’ la parte del filename che segue il . , se non contiene il . , da’ NULL da’ la prima parte del nome assoluto del file (head) quella formata dalle directories. da’ l’ultima parte del nome assoluto del file (tail) cioe’ il nome vero e proprio del file. #!/bin/tcsh echo -n “Enter filename” set filename = $< echo $filename:r echo $filename:e echo $filename:h echo $filename:t exit 197* 8.4 Variable expansion Si e’ gia’ visto precedentemente la funzione dei 3 tipi di quotes usati in Unix : ’ ’ single (forward ) quotes, “” double quotes, `` single backward quotes o backticks. Viene qui riassunto il loro comportamento con le variabili di shell : le ’ ’ prevengono ogni tipo di variable expansion la variabile ritorna cosi’ com’e’ scritta le “” raggruppano tutti i caratteri contenuti in esse in un’unica word, permette la variable expansion ma NON il globbing della wildcard ( * ). le `` causano l’immediata esecuzione del comando corrispondente, ed il suo 198* (eventuale) stdout viene sostituito al posto delle ``. le “” impediscono il globbing dello *, quindi il valore dato a name e’ ls test* > set name = ls test* > echo $name ls test_script2 test_script3 test_script4 > echo '$name' e’ come se scrivessi echo ls test* (cioe’ $name al posto di $name viene messo il suo > echo “$name” valore) e quindi ora c’e’ globbing dello * ls test* > echo `$name` test_script2 test_script3 test_script4 le ’ ’ prevengono ogni tipo di variable expansion la variabile ritorna cosi’ com’e’ scritta le “” raggruppano tutti i caratteri contenuti in esse in un’unica word, permette la variable expansion ma NON il globbing della wildcard ( * ). le `` causano l’immediata esecuzione del comando corrispondente, ed il suo 199* (eventuale) stdout viene sostituito al posto delle ``. > set name = ls test* > echo $name ls test_script2 test_script3 test_script4 > echo '$name' le ‘’ impediscono la variable $name sostitution > echo “$name” ls test* le “” permettono la variable sostitution > echo `$name` test_script2 test_script3 test_script4 ma poi impediscono il globbing dello * le ’ ’ prevengono ogni tipo di variable expansion la variabile ritorna cosi’ com’e’ scritta le “” raggruppano tutti i caratteri contenuti in esse in un’unica word, permette la variable expansion ma NON il globbing della wildcard ( * ). le `` causano l’immediata esecuzione del comando corrispondente, ed il suo 200* (eventuale) stdout viene sostituito al posto delle ``. > set name = ls test* > echo $name ls test_script2 test_script3 test_script4 > echo '$name' i backtics `` interpretano il $name comando racchiuso tra di > echo “$name” essi, lo eseguono e sostituiscono al loro posto un eventuale output ls test* mandato a stdout . > echo `$name` test_script2 test_script3 test_script4 le ’ ’ prevengono ogni tipo di variable expansion la variabile ritorna cosi’ com’e’ scritta le “” raggruppano tutti i caratteri contenuti in esse in un’unica word, permette la variable expansion ma NON il globbing della wildcard ( * ). le `` causano l’immediata esecuzione del comando corrispondente, ed il suo 201* (eventuale) stdout viene sostituito al posto delle ``. 8.5 Operatori di comparazione Gli operatori di comparazione servono nei costrutti di flow control che vedremo in seguito, come if, while etc. e sono elencati nella tabella. Negli esempi invece, viene usato il costrutto if completo solo per il primo esempio, negli altri il costrutto corretto e’ sottinteso. Tavola = == ! != && || > < >= <= assign value to variable equal to Boolean NOT NOT equal to Boolean AND Boolean OR greater than less than greater or equal to less or equal to si noti la negazione dell’operatore logico che sta in parentesi # assignment set string = pippo # equal to if( $i == 10 ) then echo “numero uguale a 10 “ endif if( $string == pippo ) then # not equal to if( $i != 2 ) then if( $string != pippo) then # greater than 1 and less than 10 if( $i > 1 && $i < 10 ) then # equal to 0 or 1 if( $i == 0 || $i == 1) then # not less than nor equal to 10 if(!($i <= 10)) then 202* 8.6 Files operators La tavola che segue riassume i tipi di file operators ammessi dalla C shell. Essi ritornano un valore true o false e vengono quindi usati nei costrutti logici (ad esempio in costrutti con if). Tavola -d -e -f -o -r -w -x -z true if file is a directory true if file exists true if file contains text true if executor of file is owner true if file is readable by executor true if file is writable by executor true if file is executable by executor true if file is empty # true if /usr/fred is a directory if( -d /usr/fred ) then # true if /tmp/file exists if ( -e /tmp/file) then # true if /usr/fred/text contains text if ( -f /usr/fred/text ) then # true if fred owns /usr/fred/file if ( -o /usr/fred/file) then #true if /usr/fred/file is readable if( -r /usr/fred/file) then #true if /usr/fred/file is writeable if( -w /usr/fred/file) then # true if /usr/fred/file is executable if( -x /usr/fred/file) then #true if /usr/fred/file is empty if( -z /usr/fred/file) then 203* 8.7 Operatori matematici Tavola Affrontiamo ora quegli operatori che permettono di eseguire calcoli aritmetici con variabili di shell che contengano valori interi. Nella tavola che segue, sono raggruppati prima gli operatori aritmetici, poi quelli che agiscono sui bit di tali variabili. Integers = + * / ++ -% Assign Add Subtract Multiply Divide Increment by 1 Decrement by 1 Modulo Bits >> << ~ ! | ^ & Right bit shift Left bit shift 1’s complement Logical negation Inclusive OR Exclusive OR AND 204* si noti @ piu’ lo spazio bianco che indica che la variabile di shell k deve avere come valore il risultato dell’operazione a destra dell’uguale. #!/bin/tcsh set i = 15 @j=3 echo “i :$i ; j :$j” # addition @ k = $i + $j echo “addition : $k” #subtraction @ k = $i - $j echo “subtraction : $k” #division @ k = $i / $j echo “division : $k” # multiplication @ k = $i * $j echo “multiplication : $k” # modulo @ k = $i % $j echo “modulo : $k” # autoincrement set k = 10 @ k++ echo “autoincrement : $k” 205* # autodecrement set k = 10 @ k- echo “autodecrement : $k” # right bit shift @ k = ( $i >> 2 ) echo “right bit shift i by 2 : $k” # left bit shift @ k = ( $i << 2 ) echo “left bit shift i by 2 : $k” # invert bits @ k = ~ $i echo “invert bits : $k” # logical negation @ k = ! $i echo “logical negation : $k” # bitwise inclusive OR @ k = ( $i | $j ) echo “bitwise inclusive OR : $k” # bitwise exclusive OR @ k = ( $i ^ $j ) echo “bitwise exclusive OR : $k” # bitwise AND @ k = ( $i & $j ) echo “bitwise AND : $k” 206* 8.8 Flow control Gli statements di flow control servono a direzionare la sequenza di istruzioni da eseguire in dipendenza dal verificarsi di determinate condizioni. Nella C shell questi comandi sono molto simili a quelli del linguaggio C e sono elencati nella tavola qui sotto. Tavola degli statements di flow control if while foreach switch goto 207* Comando if Come nel linguaggio C, questo comando provoca un branching semplice, doppio o multiplo. oppure : Sintassi oppure : : if ( condition ) statement if ( condition ) then [statements] endif oppure : if ( condition ) then [statements] else [statements] endif if ( condition ) then [statements] else if ( condition ) then [statements] … [ else if ( condition ) then statements ] ... [ else statements ] endif 208* Comando if #!/bin/tcsh # report a file executable satus echo -n “enter filename” set a = $< if (-x $a) then echo “$a is an executable” else echo “$a is not an executable” endif exit piccolo script che riporta se il file che diamo come input da terminale, e’ un eseguibile file operator che rende vera l’espressione se $a e’ un eseguibile file operator che rende vera l’espressione se $a e’ vuoto piccolo script che riporta se il file che diamo come argomento, e’ non vuoto ed in tal caso lo stampa a terminale. #!/bin/tcsh # displays a non-empty file if(-z $1) then echo “File $1 is empty” exit endif more $1 exit 209* Comando while Come nel linguaggio C, questo e’ un comando di loop, che viene eseguito finche’ una certa condizione e’ vera. Sintassi : while ( condition ) ... [statements] ... end #!/bin/tcsh # displays calendar by month set i = 1 while ($i != 13) se $i non e’ uguale a 13 cal $i 2002 @ i = ($i + 1) end echo “Calendar complete” exit 210* Comando foreach Anche questo e’ un comando di loop che esegue un blocco di statements per ogni componente di una lista di elementi. Sintassi : foreach variable ( list ) ... [statements] ... #!/bin/tcsh # displays all .txt files foreach i ( *.txt ) cat $i end exit l’uso di * crea una lista di files che terminano con .txt La variabile di shell i assume, uno per volta, tutti i valori di tale lista. end #!/bin/tcsh # displays characteristics # of files of the list set files = ( test1 test2 test3 ) foreach i ( $files ) ls -l $i end in questo esempio, la lista di exit valori che i assume, e’ stata definita direttamente nello 211* script. Comando switch Questo e’ un comando di flow control del tutto analogo al corrispondente comando in C. Il flusso di istruzione da eseguire viene diretto a quella case label la cui label corrisponde al valore della variabile dello switch. Si puo’ poi definire anche una label (comando default:) per i casi in cui la variabile dello switch non corrisponda a nessuna altra label. Infine il comando breaksw serve per far saltare fuori dal costrutto di switch e far eseguire la prima istruzione che segue endsw. Sintassi : switch ( string ) case string1: [statements] [breaksw] case string2: [statements] #!/bin/tcsh echo “select printer ; l or <cr> for laser, p for plotter” set var = $< var e’ la variabile dello switch switch ( $var ) case l: se var ha valore p il programma salta qui lpr -Plaser $1 ed esegue tutti i comandi che seguono breaksw case p: lpr -Pplotter $1 il programma salta alla prima istruzione breaksw dopo endsw poiche’ qui c’e’ breaksw default: lpr -Plaser $1 se var NON ha ne’ valore p ne’ valore l endsw il programma salta qui ed esegue tutti i exit comandi che seguono [breaksw] ... case stringn: [statements] [breaksw] [default:] [statements] endsw 212* Comando goto Il flusso d’esecuzione dei comandi viene ridiretto all’istruzione marcata dalla label label. Anche questo e’ un comando che ha una eguale controparte nel C. Sintassi : goto label In questo esempio viene stampato a terminale il valore della prima variabile passata allo script, se l’utente l’ha passata effettivamente. Nel caso contrario, viene stampato il messaggio : Variable 1 is undefined #!/bin/tcsh if ($1 == “” ) goto undefined echo “the value of variable 1 is :$1” exit undefined: echo “Variable 1 is undefined” exit si noti che la label undefined deve essere seguita da : 213* Error handling and flow control Error handling significa dirigere il flusso di istruzioni a seconda che un comando vada a buon fine o abbia esito negativo. In Unix questo si puo’ fare almeno in due modi, sia usando gli operatori logici || e && , sia usando direttamente la varibile di shell status , che assume generalmente valore 0 quando comando va a buon fine. Cominciamo con gli operatori logici Funzionamento degli operatori logici usati con comandi command 1 succeeds yes no yes no operator || || && && command 2 executes no yes yes no Sintassi OR logico : command1 || command2 Sintassi AND logico : command1 && command2 214* Error handling and flow control se la compilazione del programma in C test.c NON va a buon fine … #!/bin/tcsh cc test.c >& error || mail studente < error … spedisci un mail con gli errori di compilazione all’utente studente se nel file delle passwords esistono utenti che usano la tcsh shell … #!/bin/tcsh grep tcsh /etc/passwd > lista && mail studente < lista … spedisci un mail con l’elenco di 215* tali utenti Error handling and flow control Uso della variable di shell status La variabile status viene ridefinita dopo l’esecuzione di ogni comando o shell script. Sfortunatamente il valore assunto non e’ consistente per tutti i comandi ed e’ generalmente anche dipendente dai vari flavours di Unix. In generale si tenga presente che se status e’ 0 vuol dire che l’esecuzione del comando ha avuto successo, se status =1 vuol dire che la sintassi era giusta, ma il comando non ha in qualche modo raggiunto lo scopo che si era prefisso, infine se status ha qualche altro valore vuol dire che la sintassi non era corretta o qualche file non esiste. Ad ogni modo e’ buona norma controllare sempre come si comporta status quando lo si vuole usare in uno script. Il comando ha avuto successo, status e’ 0 Sintassi giusta, ma pallino non e’ stato trovato ; status e’ 1 Il file prrrr.txt non esiste; status e’ 2216* Error handling and flow control Uso della variable di shell status Ecco un esempio di script in cui viene eseguito il comando grep sui due argomenti passati allo script. Viene quindi sfruttata la variabile status per fare un minimo di error handling. Lo script vuole due argomenti nella chiamata : $1 e’ il pattern da cercare, $2 e’ il file in cui cercare. Gli argomenti passati a grep generano un errore di sintassi ! #!/bin/tcsh grep $1 $2 set error = $status if( $error == 0) then echo “execution successful” Il pattern non c’e’ nel else if ($error == 1 ) then file; status e’ 1. echo “nothing found” else echo “severe error found you, idiot !” endif exit 217* 8.9 Comandi built-in nella C shell E’ gia’ stato detto precedentemente dei comandi built-in nella C shell. Esempi di di tali comandi sono alias, bg, cd, dirs, echo, fg, history, if (else etc. ), jobs, kill, limit, logout, nice, popd, pushd, set, setenv, shift, switch, umask, unalias, unlimit, unset, unsetenv, which, while. Vengono introdotti qui altri comandi built-in utili nella programmazione della C shell. Si tratta di : ridireziona il flusso di istruzioni quando viene mandato un interrupt allo script determina quant’e’ il tempo di esecuzione di un comando onintr eval time source forza l’esecuzione di un comando interpretando eventuali metacaratteri presenti nel comando prende i comandi da eseguire da una sorgente (source, appunto; tipicamente un ASCII file). Eventuali definizione di shell variables e di alias NON vengono perse dopo l’esecuzione di tutti i 218* comandi contenuti nella sorgente Comando onintr Questo comando ridirige il flusso dello script quando l’utente da’ un <ctrl>C interrupt da tastiera. Il flusso di comandi dello script, invece di interrompersi semplicemente, salta alla label indicata ed esegue i comandi a partire da li’ come indicato nell’esempio seguente. #!/bin/tcsh # partial example of interrupt handling onintr pippo Se l’utente da’ un <ctrl>C … exit il comando salta alla label pippo: indicata (pippo) ed esegue echo “script terminated abnormally” i comandi che seguono exit 219* Comando eval E gia’ stato detto precedentemente che generalmente per eseguire dei comandi che non siano built-in, la C shell genera un child process. Nei casi pero’ in cui il comando sia contenuto ad esempio in una shell variable, il child process NON interpreta eventuali metacaratteri in esso presenti, ma prende ogni elemento letteralmente e questo puo’ produrre risultati del tutto non voluti. Il comando eval e’ utile in questo caso, poiche’ forza l’esecuzione da parte della current shell (cioe’ senza forking) interpretando eventuali metacaratteri presenti nel comando. L’esempio che segue dovrebbe chiarire il problema. 220* Comando eval Il comando (command string) e’ stato depositato nella variabile test Qui l’intenzione e’ di far eseguire il comando ls -l | grep example_10 Il metacarattere | non viene riconosciuto come tale ma letteralmente come nome di file! eval ci viene in soccorso interpretando | come metacarattere di piping ed eseguendo il comando come volevamo ! 221* Comando time Sintassi : time [command] Il comando time lancia un comando od uno script e ne fornisce anche il tempo che ci vuole per eseguirlo. Se non gli viene dato un argomento, time riporta il tempo usato dal parent process e da tutti i suoi child processes dall’inizio della sessione. 0 minuti e 22.21 secondi 2.801 secondi lancia lo script myscript e ne calcola il tempo 1 page (cioe’ 512 bytes) input + 1 page di output sul disco 1 page faulted in + 0 page faulted out 1 Kb di physical memory + 2 Kb di memory stack user time consumato system time consumato tempo solare trascorso % delle risorse di CPU usato 222* Comando source Questo comando serve quando si vogliono eseguire i comandi da una sorgente (source, appunto) che tipicamente e’ un file ASCII. Questo risultato si potrebbe ottenere ugualmente dando direttamente il comando sorgente da STDIN (a patto che il file abbia la protezione x on). La differenza e’ che con source eventuali definizione di shell variables ed eventuali definizioni con alias NON vengono perse dopo l’esecuzione di tutti i comandi contenuti in sorgente ma continuano a valere per la current shell. Sintassi : source [-h] sorgente Opzione : -h serve solo per mettere i comandi contenuti in sorgente nella history list (per default NON ci vengono messi) ; i comandi NON vengono effettivamente eseguiti. 223* Comando source #!/bin/tcsh # definizioni di variabili ed esecuzione \ di ls set var1 = test # ls exit pwd /home/boca ls program.f program.x prova.com test_script zoom test_script esegue direttamente lo script program.f program.x prova.com test_script zoom echo $var1 la variabile di shell var1 viene persa var1: Undefined variable dopo l’esecuzione di test_script source test_script program.f program.x prova.com test_script zoom echo $var1 test con source la variabile di shell var1 mantiene la sua definizione anche nella current shell 224* 8.10 Debugging Si puo’ fare il debugging (eliminazione degli errori di programmazione) di uno shell script eseguendo lo script mediante il comando csh con determinate opzioni; tra tutte esaminiamo qui solo -x e -v Sintassi : csh [-options] script Opzione : -x ripete le linee di comando dopo aver eseguito eventuali variable substitutions. Utile per localizzare problemi legati a variable substitutions. -v ripete le linee di comando PRIMA di aver eseguito eventuali variable substitutions. Utile per localizzare quale comando fa fallire lo script. 225* 8.10 Debugging esegue lo script ripetendo i comandi DOPO aver fatto ... … la variable sustitution esegue lo script ripetendo i comandi letteralmente, come sarebbero SENZA la variable substitution 226* Si definisco programmi di text processing quelli che leggono un file di input ASCII, lo manipolano in vari modi e generalmente producono un testo di output. In questa categoria possiamo mettere i comandi di screen editor vi e nedit gia’ visti in precedenza. Vedremo ora il comando awk che e’ un potente programma di text processing la cui versatilita’ lo avvicina ad un linguaggio ad alto livello. E’ un comando di text processing line oriented poiche’ il testo viene analizzato una linea alla volta. Le possibilita’ offerte da awk sono tra l’altro : 1) field oriented processing 5) arithmetic expressions 2) predefined variables 6) scalar variables and arrays 3) variable assignment 7) output redirection and piping 4) logical operations 227* Sintassi : awk [-options] ’program text’ file [file2 … ] dove program text ha la forma : pattern {action} ... pattern {action} Opzione : -Fdelimiter questa opzione specifica che l’ input field separator e’ delimiter invece che il blank (che e’ il default) -f awk_script specifica che i comandi da eseguire non vengono dati da terminali ma sono contenuti nel file ASCII awk_script -v var=val viene definita una variabile var che puo’ essere ‘vista’ durante l’esecuzione dei comandi di awk. A tale variabile viene anche assegnato assegnato il valore val prima di cominciare ad eseguire le altre operazioni. Azione : il comando esamina ogni riga di file (se ci sono piu’ files in input vengono concatenati e visti come un unico grande file), una riga alla volta, la scompone in campi (fields), indidua eventuali patterns, esegue eventuali azioni (actions). 228* Le single quotes ( ’ ) delimitano le combinazioni pattern - action statements ; le parentesi graffe { } isolano le actions dai patterns. Il pattern viene per primo, poi si mette l’action. Sia il pattern che l’action possono non esserci ma, non entrambi. Se il pattern manca, l’action sara’ eseguita per ogni record (cioe’ per ogni riga) di input. Se manca l’action allora viene assunta quella di default che e’ print vale a dire la stampa dell’intera riga di input. Infine in mancanza dell’opzione -F il field delimiter e’ lo spazio (blank). pattern : il primo campo sia uguale a pippo action : stampa a stdout il primo e terzo campo 229* 9.1 Definizione dei campi con i field separators Per default il delimitatore di campi (field separator) e’ qualunque un numero di blanks tra caratteri non blank. Eventuali blanks all’inizio della riga vengono trascurati. secondo campo primo campo cat dimostrazione_campi.txt primocampo secondo terzo field delimiter terzo campo 230* Si puo’ ridefinire il field separator con una qualunque stringa di caratteri, con l’opzione -F come negli esempi che seguono. A differenza del blank, piu’ field separators di seguito definiscono campi vuoti ed eventuali field separators all’inizio di una riga NON vengono trascurati da awk. quarto campo primo campo (vuoto) cat esempio.txt ::nome:cognome::via:paese awk -F: ‘{print $4}’ esempio.txt cognome il : e’ il field delimiter l’action e’ un print su stdout 231* il field delimiter e’ : pattern : uno qualunque dei campi sia uguale a boca l’action e’ un print di $0 (tutta la riga) delimitatore dei campi pattern-action file esaminato da awk 232* risultato del comando 9.2 Patterns Diamo la tavola dei tipi di patterns di awk e, nelle pagine seguenti, numerosi esempi. Tavola dei patterns di awk BEGIN esegue dei comandi prima di esaminare alcuna linea di input END esegue dei comandi dopo aver saminato tutte le linee di input /regular expression/ pattern di match (con una regular expression) relational expression pattern che contiene relational operator(s) pattern && pattern AND logico di due patterns pattern || pattern OR logico di due patterns !pattern NOT logico di un pattern pattern1?pattern2:pattern3 questo operatore ternario e’ uguale all’analogo del C. Se pattern1 e’ vero allora il pattern usato nel test logico e’ pattern2, altrimenti e’ pattern3 pattern1, pattern2 questa forma e’ chiamata pattern range. Corrisponde a tutti i recors in input che cominciano con un record che corrisponde a pattern1 fino al record che soddisfa 233* pattern2, inclusi. Patterns contenenti BEGIN od END prima dell’esame delle righe di input viene eseguita la stampa tra parentesi graffe backslash prima di return per la continuazione del comando nella prossima riga operatore aritmetico di autoincremento come quello del C dopo aver esaminato il file di input viene eseguito lo statement tra parentesi graffe 234* Pattern di match (con una regular expression) Il pattern di match e’ indicato dalla presenza delle barre in avanti (slash). Il match si verifica quando uno o piu’ campi contengono la stringa di caratteri con cui si fa il match. Quest’ultima e’ appunto quella racchiusa tra barre. Si noti che quest’ultima puo’ essere sia una stringa normale, sia una con i simboli speciali (ad es. il $ ed il ^) che si possono usare con il comando grep, con significato analogo. In UNIX sia le stringhe normali che quelle con simboli speciali vengono chiamate regular expressions. pattern : un campo qualunque sia uguale a boca action statement : print da solo, cioe’ print di tutta la riga l’output del comando awk e’ il printout di tutte le righe del file /etc/passwd che abbiano un qualunque campo uguale a boca 235* Pattern di match (con una regular expression) Il pattern di match e’ indicato dalla presenza delle barre in avanti (slash). Il match si verifica quando uno o piu’ campi contengono la stringa di caratteri con cui si fa il match. Quest’ultima e’ appunto quella racchiusa tra barre. Si noti che quest’ultima puo’ essere sia una stringa normale, sia una con i simboli speciali (ad es. il $ ed il ^) che si possono usare con il comando grep, con significato analogo. In UNIX sia le stringhe normali che quelle con simboli speciali vengono chiamate regular expressions. pattern : un campo qualunque sia uguale alla regular expression ^b (che vuol dire una stringa di caratteri che inizi con b ) l’output del comando awk e’ il printout di tutte le righe che hanno qualche campo che comincia per b 236* Pattern di match (con una regular expression) Il pattern di match e’ indicato dalla presenza delle barre in avanti (slash). Il match si verifica quando uno o piu’ campi contengono la stringa di caratteri con cui si fa il match. Quest’ultima e’ appunto quella racchiusa tra barre. Si noti che quest’ultima puo’ essere sia una stringa normale, sia una con i simboli speciali (ad es. il $ ed il ^) che si possono usare con il comando grep, con significato analogo. In UNIX sia le stringhe normali che quelle con simboli speciali vengono chiamate regular expressions. pattern : il primo campo sia uguale alla regular expression ^g ( stringa di caratteri che inizi con g ) action mancante, significa print ; l’output del comando awk e’ il printout di tutte le righe che hanno il primo campo che comincia per g 237* Pattern di match (con una regular expression) Il pattern di match e’ indicato dalla presenza delle barre in avanti (slash). Il match si verifica quando uno o piu’ campi contengono la stringa di caratteri con cui si fa il match. Quest’ultima e’ appunto quella racchiusa tra barre. Si noti che quest’ultima puo’ essere sia una stringa normale, sia una con i simboli speciali (ad es. il $ ed il ^) che si possono usare con il comando grep, con significato analogo. In UNIX sia le stringhe normali che quelle con simboli speciali vengono chiamate regular expressions. pattern : qualunque campo sia uguale alla regular expression tcsh$ che vuol dire stringa di caratteri che finisca con tcsh l’output del comando awk e’ il printout di tutte le righe che hanno qualunque campo238* che termina per tcsh Altri esempi di patterns action operatore relazionale < operatore matematico AND logico dei due patterns 239* Altri esempi di patterns se il 30 campo e’ < 10000 allora il 30 campo sia < 120 altrimenti il 40 campo sia < 120 corrisponde ai records (linee) cominciando da quello che contiene il pattern halt a quello che contiene il pattern ope all’inizio della riga. L’action non e’ indicata, quindi e’ quella di default : print $0 240* Altri esempi di patterns NOT logico (negazione) 241* 9.3 Actions Come gia’ detto, le actions sono racchiuse tra parentesi graffe. Gli statements che formano una action sono uguali a quelle disponibile nel linguaggio C. Il numero ed il tipo di actions possedute da awk lo avvicinano molto ad un vero e proprio linguaggio ad alto livello. Nel seguito, ciascuna categoria di action verra’ spiegata mediante un esempio. Tipi di action statements 1) Variable assignment 2) Formatted printing, I/O statements, output redirecting 3) Mathematical and logiacal operators, string and mathematical functions 4) Conditional, flow control and looping statements 242* Variable assignment In awk si possono definire delle variabili che possono essere scalari oppure anche vettori ad una dimensione. Esistono anche delle variabili predefinite. Le variabili sono dinamiche, cioe’ vengono create quando vengono usate per la prima volta. Inoltre, a differenza di quanto succede in molti linguaggi di alto livello, NON occorre dichiarare prima il tipo di variabile. I valori che possono assumere le variabili possono essere floating point, interi, stringhe di caratteri in dipendenza da come vengono usate. L’utente assegna valori alle variabili mediante l’uguale ( = ). Non c’e’ bisogno che la variabile x sia stata definita prima La variabile x puo’ assumere valori sia interi che alfanumerici (stringa di caratteri) ; separatore di comandi (come in C e nella C shell) 243* Variabili predefinite Come detto prima, awk ha un set di varibili predefinite (built-in variables)che l’utente puo’ usare in qualunque punto del suo script ; sono riassunte nella tavola che segue. Tavola delle variabili predefinite ARGC ARGIND ARGV CONVFMT ENVIRON il numero di argomenti dati nella linea di comando di awk, ad esclusione delle opzioni e dell’input file. l’indice in ARGV del file correntemente esaminato. array degli argomenti dati nella linea di comando di awk. L’array e’ numerato da 0 ad ARGC-1. Modificando dinamicamente ARGV si possono controllare i files di dati in input. il formato di conversione per i numeri che per default e’ “%.6g” e’ l’array contenente i valori correnti delle environment variables. Questo array e’ indicizzato dal nome della variabile d’ambiente e ciascun elemento e’ il valore di tale variabile. Ad esempio, ENVIRON[“HOME”] potrebbe essere /home/studente (vedi anche seguito la sintassi degli arrays). Da notare che se si cambia questo array all’interno di awk NON cambia il set di variabili d’ambiente visto da programmi fatti partire da awk mediante redirection o dall’uso della funzione system. 244* Variabili predefinite Come detto prima, awk ha un set di varibili predefinite (built-in variables)che l’utente puo’ usare in qualunque punto del suo script ; sono riassunte nella tavola che segue. Tavola delle variabili predefinite se c’e’ un errore di sistema durante la ridirezionamento con la la funzione getline o durante un read con getline e durante una close allora ERRNO conterra’ una stringa che descrive l’errore. FILENAME il nome del file di input corrente. FNR l’input record number nel file di input corrente. FS l’input field separator (uno spazio per default). IGNORECASE controlla la case-sensitivity di tutte le regular expressions e le operazioni con stringhe. Se esso ha un valore diverso da 0, allora tutte le operazioni che coinvolgono pattern matching, regular expressions etc. non fanno differenza tra maiuscole e minuscole. Ad es. /aB/ corrisponde alle stringhe “ab”, “aB”, “Ab” e “AB”. NF il numero di campi della riga corrente NR numero totale di input records (cioe’ righe di input) viste finora. ERRNO 245* Variabili predefinite Come detto prima, awk ha un set di varibili predefinite (built-in variables)che l’utente puo’ usare in qualunque punto del suo script ; sono riassunte nella tavola che segue. Tavola delle variabili predefinite OFMT OFS ORS RS RSTART RLENGTH SUBSEP il formato di output per i numeri, per default “%.6g”. Modificando questa variabile si puo’ modificare l’output del comando print NON formattato; vedi in seguito nella sezione sull’ I/O. l’ output field separator, uno spazio per default. l’ output record separator; per default e’ un newline. l’ nput record separator; per default e’ un newline. l’indice del primo carattere corrispondente ai criteri della funzione match( ) ; 0 se non ce n’e’ nessuno. la lunghezza della stringa individuata da match( ) ; -1 se non ce n’e’ alcuna. il carattere usato per separare gli indici ‘multipli’ negli arrays, per default e’ “\034” (cioe’ il carattere ASCII corrispondente al numero ottale 34 ( 1C in esadecimale) ; vedi seguito nella sezione dedicata agli arrays). 246* Variabili predefinite Come detto prima, awk ha un set di varibili predefinite (built-in variables)che l’utente puo’ usare in qualunque punto del suo script ; sono riassunte nella tavola che segue. Tavola delle variabili predefinite $0 $n length(var) tutto il record ( tutta la riga ) corrente il field nesimo del record corrente lunghezza (in caratteri) del contenuto di var 247* Vettori Come gia’ detto, in awk si possono definire delle variabili anche vettori. Tali arrays vengono indicati, come in C, con un nome seguito da parentesi quadre ( [ ] ). Non e’ necessario dichiararne il tipo prima poiche’ vengono creati al momento dell’uso. La loro dimensione e’ solo 1 . Tuttavia se ne puo’ sfruttare una notevole particolarita’, vale a dire che l’indice dei vettori e’ una stringa di caratteri (proprieta’ associativa dell’indice del vettore ) per simulare arrays a piu’ dimensioni. Il vettore v ha indici alfanumerici ( hash table ) 248* Vettori Come gia’ detto, in awk si possono definire delle variabili anche vettori. Tali arrays vengono indicati, come in C, con un nome seguito da parentesi quadre ( [ ] ). Non e’ necessario dichiararne il tipo prima poiche’ vengono creati al momento dell’uso. La loro dimensione e’ solo 1 . Tuttavia se ne puo’ sfruttare una notevole particolarita’, vale a dire che l’indice dei vettori e’ una stringa di caratteri (proprieta’ associativa dell’indice del vettore ) per simulare arrays a piu’ dimensioni. Infatti, se il vettore viene indicizzato con una lista di espressioni : expr1, expr2,expr3 … allora l’indice del vettore diventa la stringa risultato della concatenazione dei valori (come stringhe) di ciascuna espressione, separate dal valore della variabile SUBSEP (vedi tavola precedente delle variabili predefinite). In tal modo e’ possibile simulare la presenza di piu’ indici per il vettore. Il vettore v ha un UNICO indice dato dalla concatenazione dei valori A B C separati tra loro dal separatore \034 (cioe’ dal valore contenuto in SUBSEP) Il vettore vec ha un UNICO indice dato dalla concatenazione dei valori 3 1 5 separati tra loro dal separatore \034 (cioe’ dal valore di SUBSEP). Cosi’ il riferimento al vettore vec nello statement print e’ formalmente identico a quello di un vero 249* vettore multidimensionale Vettori Esiste in awk l’operatore in che serve per determinare se un valore e’ un possibile indice di un vettore. Valori possibili dell’indice di vec sono 1 e 3 operatore in che restituisce un valore (true o false ) che e’ possibile usare in uno statement logico (if in questo esempio) 250* Formatted printing, I/O statements, output redirecting Il printout a stdout si ottiene con lo statement print come abbiamo gia’ visto in numerosi esempi precedenti. Si noti che print e’ anche l’action di default nel caso l’utente non ne indichi esplicitamente di proprie. Nel caso invece si voglia formattare l’output si puo’ usare, in modo del tutto analogo al C, lo statement printf. Sintassi : { printf “format statement” expression } dove program text ha la forma : pattern {action} ... pattern {action} printout di variabile floating point, in un campo da 8 cifre con 2 cifre decimali { printf “%8.2f”,i } { printf “variabile intera %10d\n”,i } { printf “formato variabile %10.6g\n”,i} printout di variabile intera in campo di 10 cifre printout di variabile con formato variabile in campo di 10 cifre con 2 cifre significative 251* action : printout delle variabili i e $1 con un campo di 5 interi e come stringa rispettivamente 252* In awk e’ possibile ridirigere l’output, normalmente diretto a stdout, ad un file oppure ad un altro comando con un piping. > : ridirezione dell’output da stdout a users_file.lis >> : ridirezione dell’output da stdout a users_file.lis piping dell’output di awk al comando head -3 253* Esistono anche altri statements che riguardano l’ I/O; sono riassunti nella tavola seguente Tavola degli statements di Input/Output close(file) getline getline < file getline var getline var < file next nextfile close file or pipe set $0 equal to the next input line; set NF, NR, FNR set $0 equal to the next input line of file ; set NF set var equal to the next input line; set NR, FNR set var equal to the next input line of file stop processing the current input record. The next input record is read and processing starts over with the first pattern in the awk program. If the end of the input is reached, the END block(s), if any, are executed. stop processing the current input record. The next input record read comes from the next input file. FILENAME and ARGIND are updated, FNR is reset to 1 and processing starts over with the first pattern in the awk program. If the end of the input data is reached, the END block(s), if any, are executed. 254* Esistono anche altri statements che riguardano l’ I/O; sono riassunti nella tavola seguente Tavola degli statements di Input/Output fflush([file]) flush any buffers associated with the open output file or pipe file . If file is missing, then stdout is flushed. If file is the NULL string, then all open output files and pipes have their buffers flushed. system(command line) executes command line and returns the status. The command is executed in the Bash shell (sh). 255* action : quando NR (numero di records) e’ uguale a 3 salta un record e poni il prossimo input record in $0 non ha stampato la terza riga perche’ l’ha saltata con next 256* pattern : NR sia <= 3 esegue il comando di (Bash) shell date 257* Operatori matematici e logici Vengono di seguito elencati nella tavola gli operatori matematici e logici disponibili in awk in ordine di priorita’ decrescente (gli operatori in cima all’elenco vengono eseguiti per primi, quelli sulla stessa riga hanno la stessa priorita’ e vengono eseguiti da sinistra a destra). Si nota una volta di piu’, che sono uguali agli operatori del C ; hanno anche la stessa sintassi. Tavola degli operatori matematici e logici ( ) $ ++ -^ + - ! * / % + space <> parenthesis field reference increment and decremet, both prefix and postfix exponentiation (also ** ) unary plus, unary minus, negate value of expression multiply, divide and remainder (modulo) addition and subtraction string concatenation less than, greater than 258* Operatori matematici e logici Vengono di seguito elencati nella tavola gli operatori matematici e logici disponibili in awk in ordine di priorita’ decrescente (gli operatori in cima all’elenco vengono eseguiti per primi, quelli sulla stessa riga hanno la stessa priorita’ e vengono eseguiti da sinistra a destra). Si nota una volta di piu’, che sono uguali agli operatori del C ; hanno anche la stessa sintassi. Tavola degli operatori matematici e logici <= >= != == ~ !~ less than or equal to, greater than or equal to not similar to, similar to match ( for example, $2~/A||B||C/ ), no match ( for example, $2!~/A||B||C/ ) in array membership && Boolean AND || Boolean OR ?: the C conditional expression = += -= *= /= %= ^= assignments 259* pattern : quando NR e’ uguale a 5 autoincremento di 1 il resto di $4 / 3 elevamento alla 4a potenza 260* String functions Il comando awk possiede anche una notevole varieta’ di funzioni che manipolano le stringhe di caratteri. Tavola degli string operators gensub(r , s , h , [, t ] ) gsub(r , s , [, t ] ) index(string, substring) length(string) match (s , r ) search the string t for matches of the regular expression r . If h is a string beginning with g or G, then replace all matches of r with s. Otherwise, h is a number indicating which match of r to replace.If no t is supplied $0 is used insted. for each substring matching the regular expression r in the string t , substitute the string s , and return the number of substitutions. If t is not supplied, use $0 . starting position of string in substring; if not found returns 0 length of string returns the position in s where the regular expression r occurs, or 0 if r is not present, and sets the values of RSTART and RLENGTH 261* String functions Il comando awk possiede anche una notevole varieta’ di funzioni che manipolano le stringhe di caratteri. Tavola degli string operators sprintf(fmt , expr-list) prints expr-list according to fmt and returns the resulting string split(string, array, “separator”) separates string into elements of array according to the field separator sub(r , s , [, t ] ) just like gsub( ) but only the first matching substring is replaced substr(string, position, length) substring of string , starting at position , and length characters long tolower( string ) returns a copy of the string string with all the upper-case characters in string translated to their corresponding lower-case counterparts. Non-alphabetic characters are left unchanged. toupper ( string ) returns a copy of the string string with all the lower-case characters in string translated to their corresponding upper-case counterparts. Non-alphabetic characters are left unchanged. 262* inizializza la variabile nc a 0 action : incrementa la variabile nc della lunghezza (numero di caratteri) di ciascuna linea di input action : splitting del 40 campo del record di input, secondo il field separator : e creazione del vettore time con dentro il risultato dello splitting action : printout degli elementi del vettore time 263* solo un BEGIN ed un END in questo awk script; in pratica il file di input e’ irrilevante 264* Mathematical functions La tabella che segue mostra le funzioni matematiche disponibili con awk. Tavola delle funzioni matematiche atan2(y , x) cos(expr) exp(expr) int(expr) log(expr) rand ( ) sin(expr) sqrt(expr) srand(expr) preturns the arctang of y /x in radians returns cosine of expr (which is in radians) exponential function truncates to integer natural logarithm returns a andom number between 0 and 1 returns sine of expr (which is in radians) returns the square root function uses expr as a new seed for the random number generator 265* pattern : NR minore di action : calcolo di sqrt(NR) e log(NR) 266* Conditional, flow control and looping statements Sono uguali a quelli del linguaggio C. Tavola dei conditional, flow control e looping statements if(condition) statement [ else statement ] while (condition) statement do statement while condition for(expr1 ; expr2 ; expr3 ) statement for( var in array ) break continue exit [ expression ] { statements } 267* 268* action : loop while action : test del loop while 269* loop for con la stessa sintassi del C # esempio 1 print del contenuto della variabile for (x = 1; x<=NF; x++) { print $x } x (cioe’ $1, $2, $3 .. etc.) … # esempio 2 loop for con l’uso dell’operatore in for (x in test;) {print x, test[x] } … # esempio 3 salta fuori dal loop for (x = 1; x<=NF; x++) { if( $x == “halt”) break } e continua con gli ... statements seguenti # esempio 4 for (x = 1; x<=NF; x++) { if( $x == “end”) continue } forza l’esecuzione del prossimo ciclo del loop (a partire dall’inizio del loop) abbandonando l’esecuzione di quello corrente 270* # esempio 1 for (x = 1; x<=NF; x++) { print $x } … # esempio 2 for (x in test;) {print x, test[x] } … # esempio 3 forscarta (x = 1;il x<=NF; x++) { if( record corrente e $x == “halt”) break } salta fuori dal loop e va direttamente ... legge il prossimo record, ad END oppure, in mancanza di # esempio 4 il flusso di comandi ricominciando quest’ultimo, esce }dai comandi di awk for (x = 1;PRIMO x<=NF;comando x++) { if( $x == “end”) continue DAL … # esempio 5 for (x = 1; x<=NF; x++) { incr += 1 ; if (incr > 100) exit } ... scarta il record corrente e # esempio 6 legge il prossimo record, { for (x = 1; x<=NF; x++) if( NF < 4) getline } ricominciando il flusso di ... comandi dal punto # esempio 7 appena dopo getline { for (x = 1; x<=NF; x++) if( NF == 1) next } 271* Sommario Come esempio finale dell’uso di awk viene mostrato un awk script che controlla se uno o piu’ files di testo hanno due parole adiacenti identiche (errore tipografico piuttosto comune) e riporta tale evenienza in output. numero totale di linee di input esaminate finora FILENAME :nome del file correntemente esaminato NF numero di fields nel record correntemente esaminato 272* 273*