Sistemi Operativi I - Appunti

Page 1

2012

Sistemi Operativi Appunti del Corso di Sistemi Operativi - A.A. 2011-12 UniversitĂ del Salento

Luca Marzo • luca.marzo@live.com


2

Introduzione Questi appunti nascono dall’esigenza di avere uno strumento unitario che raccogliesse tutti i comandi visti nel corso delle lezioni tenute dal Prof. Franco Tommasi della Facoltà di Ingegneria, Università del Salento. Lungi dal sostituire un libro di testo, queste pagine hanno l’unico scopo di fornire un rapido supporto per l’utilizzo di una serie di comandi per il terminale di Mac OS X e GNU/Linux.

Ringraziamenti È doveroso, a conclusione di questo lavoro di stesura di appunti ringraziare (in ordine sparso) le persone che, a vario titolo, hanno contribuito alla correzione ed al miglioramento degli appunti.         

Prof. Franco Tommasi Giampiero D’Autilia Luca De Pandis Simone Laierno Arianna Leverè Giorgia Indraccolo Alessia Cortese Eugenia Longhin Erica Marzo

Note e correzioni Sono graditi suggerimenti e correzioni da inviare all’indirizzo di posta luca.marzo@live.com Questi appunti sono distribuiti liberamente e sono scaricabili dal seguente link: http://dl.dropbox.com/u/49017444/os.pdf Gli script creati a lezione sono disponibili al seguente link: http://dl.dropbox.com/u/49017444/os-script.zip


3

Sistemi Operativi Comando

Descrizione

cd / ls -la cd

Cambia Directory -> Root Vedi cartelle e file presenti nella cartella corrente ed i relativi dettagli Cambia directory (Specificare la cartella di destinazione)

Cartella

Sistema Operativo

Descrizione

Volumes bin

MacOS X MacOS X - GNU/Linux

etc tmp usr

MacOS X - GNU/Linux MacOS X - GNU/Linux MacOS X - GNU/Linux

sbin dev var

MacOS X - GNU/Linux MacOS X - GNU/Linux MacOS X - GNU/Linux

Mostra tutti i volumi montati sulla macchina in uso Utility di sistema che non richiedono privilegi particolari Contiene file di configurazione della macchina Cartella di file temporanei Contiene tutti i file/utility necessarie all'utente/i in modalità multiuser Utility di sistema che richiedono privilegi

Cartella

Sistema Operativo

Descrizione

tmp home

GNU/Linux GNU/Linux

usr

GNU/Linux

var sbin media mnt

GNU/Linux GNU/Linux

File temporanei Directory in cui vengono piazzate le directory degli utenti LOCALI residenti nel sistema. È presente nella stragrande maggioranza dei sistemi Unix-like e UNIX. In Mac OS X, il suo ruolo è sostituito da /Users. Contiene tutti i file/utility necessarie all'utente/i in modalità multiuser Contiene file soggetti a variazioni (es. logs) Utility di sistema che richiedono privilegi

GNU/Linux

Volumi esterni

Contiene file soggetti a variazioni (es. logs)

Si consiglia la consultazione della seguente pagina di manuale relativa alla descrizione della gerarchia del file system: http://www.kernel.org/doc/man-pages/online/pages/man7/hier.7.html

Comando

Descrizione

ssh nomeutente@dominio.tld clear who

Connetti ad una sessione SSH (Secure Shell) Pulisci la schermata del terminale Restituisce a video tutti gli utenti connessi attualmente alla macchina Restituisce il nome utente dell’utente attualmente connesso al sistema Disconnessione

whoami exit


4

Combinazione da tastiera

Comando UNIX

CTRL+C CTRL+D CTRL+A CTRL+E TAB ⌘S

Chiudi la linea di comando (End-Of-Text Character) Termina (End-Of-Transmission Character) Torna ad inizio riga Vai a fine riga Autocompletamento Salva Tilde ~ (Option+F5)

F5

⌥ ⌘⎋

Uscita forzata Option (Alt) + Command (Mela) + Esc

Scorciatoie da tastiera MacOS X: http://support.apple.com/kb/ht1343?viewlocale=it_it&locale=it_it Comandi comuni Unix: http://www.ensyncsolutions.com/library/unix_commands.pdf

Tabella delle ridirezioni:


5

Comando

Descrizione

mkdir nomecartella rmdir nomecartella touch nomefile rm nomefile mv1 file1 file2

Crea una cartella di nome “nomecartella” Elimina la cartella di nome “nomecartella” Crea un file vuoto di nome “nomefile” Elimina il file di nome “nomefile” Rinomina/Sposta il file sorgente nel file di destinazione, se il file di destinazione esiste, sarà sovrascritto. Informazioni sul file Informazioni dettagliate sul file indicato Verifica l’esistenza2 del file “nomefile” nella cartella parent3 e fornise informazioni dettagliate su di esso. Visualizza la cartella di lavoro corrente Sposta il file “nomefile” nella cartella parent Sposta il file “nomefile” dalla cartella parent alla cartella attuale Copia “file1” in “file2” 4 Visualizza l’elenco dei comandi utilizzati (storico) Esegui il comando n°155 dalla cronologia dei comandi utilizzati. Ripete ciò che è scritto dopo, ad esempio “testo”

ls nomefile ls -la nomefile ls -la ../nomefile pwd mv nomefile ../nomefile mv ../nomefile . cp file1 file2 history !155 echo testo

Attenzione! Per inserire uno spazio nel nome di un file è necessario inserire un simbolo di backslash “\” prima dello spazio: es. nome\ del\ file

Comando “Move” - http://man.cx/mv Esiste un comando specifico per verificare l’esistenza di un file: test(1). Es: [ -e ../file ] http://man.cx/test 3 Parent: cartella di livello superiore alla cartella corrente. 4 Fare riferimento alla relativa pagina di manuale - http://man.cx/cp 1 2


6

Permessi Ogni file ha un set di privilegi/permessi e sono elencati nelle prime 10 colonne dell’output del comando ls -la

d

r

w

x

r

-

x

r

-

x

Tipo File

Lettura

Scrittura

Esecuzione

Lettura

Scrittura

Esecuzione

Lettura

Scrittura

Esecuzione

Permessi Owner

Permessi Gruppo

Permessi Utente

Mnemonicamente è utile l’acronimo UGO (User - Group - Others) Nella prima colonna si possono trovare i seguenti valori:

Valore

Descrizione

d -

Directory (Cartella) File regolare

Le altre colonne possono riportare i seguenti valori:

Valore

Descrizione

r w x -

Lettura Scrittura Esecuzione Nessun permesso

Permessi in formato Ottale I permessi possono essere espressi anche in formato ottale, segue uno schema:

Valore

Ottale

Descrizione

r w x

4 2 1

Lettura Scrittura Esecuzione

In questo sistema, la combinazione di permessi r+w+x è uguale a 4+2+1 = 7, di conseguenza il 7 corrisponde ai massimi privilegi sul file. Utilizzando il sistema ottale, i 9 valori relativi ai privilegi sul file, si riducono a soli 3 valori:

7

7

7

Owner

Gruppo

Utente

I tre valori utilizzati nel sistema ottale possono essere sommati tra di loro e di conseguenza generare differenti combinazioni corrispondenti ad una determinata tipologia di permessi:  Il valore 3, corrisponde alla combinazione wx, cioè il risultato della somma di "1+2", in questo modo si assegnano i permessi di esecuzione e scrittura.  La cifra 5, corrisponde alla combinazione rx, cioè il risultato della somma di "1+4", in questo modo si assegnano i permessi di esecuzione e lettura.  La cifra 6, corrisponde alla combinazione rw, cioè il risultato della somma di "2+4", in questo modo si assegnano i permessi di scrittura e lettura.  La cifra 7, corrisponde alla combinazione rwx, cioè il risultato della somma di "1+2+4", in questo modo si assegnano i permessi di esecuzione, scrittura e lettura.


7

Assegnare/Modificare i privilegi di un file Comando 5

chmod chmod chmod chmod

permessi nomefile g+w nomefile g-rw nomefile 770 nomefile

chown6 newowner file chgrp7 newgroup file

Descrizione Assegna i permessi al file o alla directory indicata Assegna i permessi di scrittura al gruppo per il file indicato Elimina i permessi di scrittura e lettura al gruppo per il file Assegna i permessi completi al file per owner e gruppo, nessun permesso agli altri. Cambia il proprietario del file in “newowner” Cambia il gruppo per il file in “newgroup”

Comando

Descrizione

edit nomefile nano nomefile which nomecomando

Apri il file “nomefile” in modalità modifica con TextWrangler (MacOS) Modifica il file “nomefile” da terminale con l’editor Nano (GNU/Linux) Visualizza a schermo il file (ed il path) che eseguo quando utilizziamo il comando “nomecomando”

Utilizzo del manuale Comando

Descrizione

man nomecomando man cp BARRA SPAZIATRICE B Q /read

Apre la pagina di manuale relativa al comando “nomecomando” Apre la pagina di manuale relativa al comando “cp” Avanza di una schermata nel manuale Torna indietro Chiudi il manuale e ritorna al terminale Cerca “read” nel manuale

Comando

Descrizione

wc nomefile wc stdin9 + CTRL+D cat nomefile cat stdin + CTRL+D > < |

Conta le righe, le parole ed i caratteri presenti nel file “nomefile” 8 Accetta input dallo stdin fino al comando CTRL+D Visualizza nel terminale il contenuto del file “nomefile” Accetta input dallo stdin fino al comando CTRL+D Ridirigi lo stdout10 Ridirigi lo stdin Il carattere pipe (tubo) mette in comunicazione lo stdout di un comando allo stdin di un altro comando.

Alcuni esempi di utilizzo di comandi concatenati con il pipe

Comando

Descrizione

ls -la | wc rev

Manda in input al comando “wc” l’output del comando “ls -la” Rovescia ogni riga che gli viene fornita come input

Comando chmod: Change the File Mode - http://man.cx/chmod Comando chown: Change the File Ownership - http://man.cx/chown 7 Comando chgrp: Change the File Group Ownership - http://man.cx/chgrp 8 Comando wc: Word, Line and Byte or Character Counter - http://man.cx/wc 9 Stdin: Standard Input, in generale la tastiera 10 Stdout: Standard Output, in generale il terminale, lo schermo 5 6


8

ls -la | rev ls -la | rev | edit ls -la | rev | sort comando >>11 nomefile history >> nomefile uniq cut13 ls -la | cut -c1-10 ls -la | cut -c1-5, 10-15 grep pattern file cat nomefile.txt | grep wc

Prende in input e rovescia l’output del comando “ls -la” Prende in input e rovescia l’output del comando “ls -la” ed apre TextWrangler con quell’input. Prende in input e rovescia l’output del comando “ls -la” ed ordina l’output Aggiungi l’output di un comando ad un file “nomefile” già esistente Salva la cronologia dei comandi in un file dal nome “nomefile” Elimina dal file di input righe adiacenti uguali12 Taglia i campi selezionati da ogni riga dell’input Taglia dall’input le prime 10 colonne Taglia dall’input le prime 5 colonne e le colonne dalla 10 alla 15 Filtra una stringa pattern all’interno di un file Cerca “wc” nel file “nomefile.txt”

Script È possibile creare degli script personalizzati che eseguano un set di comandi quando sono lanciati. Ogni script inizia con la cosiddetta riga dello “Shebang”14 che indica al terminale di eseguire lo script con bash15. La riga dello shebang si compone come segue: #!/bin/bash Cioè dai caratteri #! e dal percorso dell’interprete (in questo caso “bash”) che deve eseguire lo script. Il carattere # posto all’inizio di una riga dello script indica che tale riga costituisce un commento, pertanto essa non viene eseguita dall’interprete. Prima di eseguire uno script, è necessario renderlo eseguibile assegnando i privilegi di esecuzione con l’apposito comando chmod: chmod 700 nomescript # assegno i permessi di esecuzione esclusivamente all’owner del file Per eseguire lo script, supponendo che si trovi nella cartella di corrente16 scriviamo nel terminale il seguente comando: ./nomescript $PATH è una variabile d’ambiente tipica dei sistemi operativi Unix che specifica un insieme di directory che contengono i programmi eseguibili. Generalmente tali percorsi sono: /bin /usr/bin /usr/local/bin Per visualizzare il valore della variabile sul sistema in uso, digitare: echo $PATH Append ( >> ): aggiunge contenuto ad un file esistente Si consiglia di lavorare su file già ordinati mediante il comando sort 13 Comando Cut - http://man.cx/cut 14 Shebang: http://en.wikipedia.org/wiki/Shebang_(Unix) 15 Bourne Again Shell: shell testuale del progetto GNU usata nei sistemi operativi Unix e Unix-like 16 Per verificare la cartella di lavoro corrente (Current Working Directory) utilizzare il comando pwd 11 12


9

L’insieme delle variabili predefinite nella macchina in uso è visibile utilizzando il comando seguente: env17

Comando

Descrizione

a=34 echo $a echo $((4*67)) echo !! c=$((4*67)) c=‘$(4*67)’

Dichiara una variabile a18 assegnandole il valore 34 Visualizza il valore della variabile a Stampa una stringa contenente l’output di un comando Sostituisce l’ultimo comando Assegna il risultato dell’operazione alla variabile c Assegna la stringa alla variabile c

Per copiare un file da una macchina all’altra, eseguire il comando scp19: scp nomefile utente@dominio.tld:cartella Il comando scp utilizza ssh per copiare il file dal computer in uso ad un altro computer remoto. Per creare un file contenente informazioni sugli utenti connessi al computer eseguire il seguente comando: echo who | cut -f1 -d' ' | sort | uniq | wc -l >> risultati La sintassi precedente eseguirà il comando who e ne filtrerà l’output, eliminando il primo campo (-f1) utilizzando come separatore lo spazio vuoto (-d‘ ’), eseguirà l’ordinamento (sort), eliminerà le righe duplicate (uniq), eseguirà il conteggio delle righe (wc -l) e scriverà il tutto nel file “risultati” (>> risultati) . Quello analizzato sopra è un classico esempio di concatenazione di comandi eseguiti grazie al carattere di pipe |.

Processi Un processo è un programma in esecuzione. Un sistema multitasking 20 esegue contemporaneamente più processi. Ad ogni processo è assegnato un quantitativo di tempo di esecuzione, la slice21 tipica è pari a 10ms. Nei sistemi operativi Unix e Unix-like PID è l'acronimo di process identifier (identificativo di processo) ed è un numero intero non negativo assegnato automaticamente che identifica in maniera univoca un processo all'interno del sistema e rimane costante per tutta la durata di generazione ed esecuzione del processo cioè fino alla sua terminazione. Il PID è un attributo del process control block.

Il comando env sta per “environment” - http://man.cx/env Le variabili definite nella shell non sono visibili dagli script (Scope delle variabili) 19 Comando scp: secure copy - http://man.cx/scp 20 Multitasking: http://it.wikipedia.org/wiki/Multitasking e Time-Sharing: http://it.wikipedia.org/wiki/Timesharing 21Multitasking - http://en.wikipedia.org/wiki/Preemption_(computing) 17 18


10

Dal terminale è possibile avviare un “task manager”, che fornisce una vista interattiva dei processi, aggiornata ogni secondo, utlizzando il seguente comando: top Ulteriori comandi consentono la gestione dei processi e la visualizzazione di numerose informazioni sui processi in esecuzione.

Comando

Descrizione

top q ps tty ps -ef

Vista processi, aggiornata ogni secondo Uscita dal comando “top” “Process Show”, visualizzazione statica dei processi22 Visualizza il terminale attualmente utilizzato23 Visualizza i processi applicando una specifica formattazione Colonne UID (User ID) e PID (Process ID) Conta le righe stampate dal comando precedente Applica la paginazione per l’output del comando precedente: b per pagina precedente, n per successiva, / per cercare. Visualizza il PID del bash Visualizza l’ID dell’utente corrente sulla macchina Visualizza l’ID utente della root Visualizza le informazioni sugli account utente24 applicando la paginazione Cerca informazioni sull’account “nome” nel file degli account utente Stampa i dettagli relativi al file del comando “ps” Stampa i dettagli relativi al file del comando “ssh” Visualizza il nome del sistema su cui stiamo lavorando25 Ulteriori dettagli sul sistema in uso26

ps -ef | wc -l ps -ef | less ps -p $$ id id root less /etc/passwd grep nome /etc/passwd ls -la $(which ps) ls -la $(which ssh) uname uname -a

Comandi condizionali Comando

Descrizione

echo $?

Restituisce 0 se il comando ha funzionato, 1 se ha fallito. Si basa sugli Exit Status dei vari comandi Lista di comandi, può essere composta anche da un solo comando Lista di comandi separati dal simbolo di semicolonna “;” Verifica l’esistenza del file “nomefile” 27 Valuta l’espressione, verificando se il primo numero è algebricamente maggiore del secondo numero. La seconda riga, restituisce 0 se l’espressione è vera, 1 se l’espressione è falsa. In questo caso 0 Valuta l’espressione, verificando se il primo numero è maggiore del secondo numero. La seconda riga, restituisce 0 se l’espressione è vera, 1 se l’espressione è falsa. In questo caso 1. Vedi il percorso del comando [ . Il comando [ sostituisce test È equivalente all’utilizzo del comando test

date ; who if date; echo ciao; fi test -f nomefile test 11 -gt 9 echo $? test 11 \> 9 echo $? which [ [ 11 \> 9 ]

Process Show mostra esclusivamente i processi dell’utente che sono legati ad un terminale - http://man.cx/ps Nei sistemi Unix-like, anche i terminali sono visti come se fossero file 24 File contenente informazioni sugli account utente - http://en.wikipedia.org/wiki/Passwd_(file) 25 Su MacOS X restituirà Darwin, il nome del kernel - http://en.wikipedia.org/wiki/Darwin_(operating_system) 26 Comando uname: http://man.cx/uname 27 Il comando test valuta un’espressione - http://man.cx/test 22 23


11

È possibile costruire delle liste di comande anche utilizzando il comando “[”: if [ 11 \> 9 ]; then date; fi Nel comando precedente, così come nella tabella precedente, il simbolo di “maggiore” (>) è stato preceduto dal simbolo di backslash (\); ciò per impedire alla shell di considerare il simbolo > come carattere di redirect dell’output.

Alcuni script e la portabilità MacOS X / Linux Il comando stat28 visualizza lo stato del file system oppure di un singolo file. Il seguente script, chiamato bistat, consentirà l’esecuzione del comando stat sia su macchine equipaggiate con MacOS X sia su sistemi GNU/Linux. #!/bin/bash # bistat if[ $(uname) == Darwin ]; then stat -x $1; else stat $1; fi Quando si utilizzano le variabili, è necessario far precedere il nome dal simbolo $. Una versione alternativa dello script bistat potrebbe essere la seguente: #!/bin/bash # bistat stringa=$(uname) if[ stringa == Linux ] then stat $1 else -x $1 fi O ancora: #!/bin/bash # bistat stringa=$(uname) comando1="stat $1" comando2="stat -x $1" if[ stringa == Linux } then $comando1 else $comando2 Tipi di parentesi: () [] {}

28

Brackets (Round Brackets) Square Brackets Brace Brackets

Comando stat - http://man.cx/stat


12

Quoting Esistono due tipi di quoting29 e tre simboli che consentono di attivarne le funzionalità:

STRONG QUOTING

WEAK QUOTING

Annulla il metavalore di qualsiasi carattere

Salva il metavalore di alcuni caratteri rispetto allo strong quoting.

Simboli di quoting ‘’ “” \

Strong Quoting Weak Quoting Backslash

Wildcards Esistono alcuni caratteri “Jolly” che la shell interpreta in modo particolare. Wildcard * ? [ ] ~

Descrizione Sostituisce uno o più caratteri (compreso il carattere nullo) all’interno del nome di un file o della sua estensione. Sostituisce un solo carattere all’interno del nome di un file o della sua estensione. Le parentesi quadre racchiudono un elenco di caratteri, ognuno dei quali può sostituire un singolo carattere in una posizione. Un trattino (hyphen) usato all’interno delle [ ] denota un range di caratteri da sostituire, es. [a-z] oppure [0-9] Il simbolo di tilde, ad inizio parola, espande il nome della home directory dell’utente attuale. Se il simbolo tilde è seguito dal nome di un altro utente, farà riferimento alla home directory dell’utente indicato.

Espansioni della shell La shell espande in un particolare ordine dopo la divisione in parole (token separati da spazi o tabulatori). Tipi di espansione30:  Brace Expansion  Tilde Expansion  Parameter Expansion  Command Substitution  Arithmetic Expansion  Process Substitution  Word Splitting  Pathname Expansion ( *, ? ) Brace Expansion echo a{b,c,d}e

29 30

http://wiki.bash-hackers.org/syntax/quoting#weak_quoting Shell Command Language - http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html


13

Il comando restituirà le seguenti combinazioni: abe, ace, ade. Allo stesso modo, grazie alla brace expansion della shell si possono ottenere tutte le combinazioni tra queste due coppie di opzioni, eseguendo il comando: echo {1,X,2},{1,X,2} E ancora, è possibile cancellare tutti i file dal nome composto dalla parola “file” seguita da una combinazione di 0, 1 e 2. (es. file001, file000, file002, file012, ecc.) rm file[0-2][0-2][02]

File e directory In Unix, a differenza di quanto avviene in altri sistemi operativi, tutti i file vengono tenuti all’interno di un unico albero la cui radice (quella che viene chiamata root directory) viene montata all’avvio. Un file viene identificato dall’utente usando quello che viene chiamato pathname, cioè il percorso che si deve fare per accedere al file a partire dalla root directory, che è composto da una serie di nomi separati da una “/”. Una directory è anch’essa un file, solo che è un file particolare che il kernel riconosce come tale. Il suo scopo è quello di contenere una lista di nomi di file e le informazioni che associano ciascun nome al contenuto. Dato che questi nomi possono corrispondere ad un qualunque oggetto del filesystem, compresa un’altra directory, si ottiene naturalmente un’organizzazione ad albero inserendo nomi di directory in altre directory. Il nome completo di un file viene chiamato pathname ed il procedimento con cui si individua il file a cui esso fa riferimento è chiamato risoluzione del nome (filename resolution o pathname resolution). Una delle differenze principali con altri sistemi operativi è che per unix tutti i file di dati sono identici e contengono un flusso continuo di byte. Un’altra differenza è nel formato dei file di testo: in Unix la fine riga è codificata in modo diverso da Windows, in particolare il fine riga è il carattere LF (o \n) al posto del CR (\r) del vecchio MacOS e del CR LF di Windows. Il filesystem Unix Lo spazio fisico di un disco viene usualmente diviso in partizioni; ogni partizione può contenere un filesystem. La strutturazione tipica dell’informazione su un disco che utilizza il filesystem ext2 prevede una separazione dei dati in block group che replicano il superblock31. È comunque caratteristica comune di tutti i filesystem per Unix, prevedere una divisione fra la lista degli inode e lo spazio a disposizione per i dati e le directory.32 È importante tenere presente che: 1. L’inode contiene tutte le informazioni (metadati) riguardanti il file: tipo di file, permessi di accesso, dimensioni, puntatori ai blocchi fisici che contengono i dati. Il comando stat fornisce informazioni che provengono dall’inode. Dentro una directory si troverà esclusivamente il nome del file ed il numero dell’inode ad esso associato. 2. Si possono avere più voci che puntano allo stesso inode. Ogni inode ha un contatore che contiene il numero di riferimenti che sono stati fatti ad esso (link count); solo quando questo contatore si annulla i dati del file vengono rimossi dal disco. Tale funzione è detta unlink e in realtà non cancella i dati del file, ma si limita ad eliminare la relativa voce da una directory e decrementare il numero di riferimenti nell’inode. Ogni filesystem contiene un superblock che contiene informazioni sul filesystem: tipo di filesystem, dimensione, stato, informazioni sulle altre strutture di metadati. 32 GaPiL - pg. 103-105 - http://gapil.gnulinux.it/files/2011/12/gapil.pdf 31


14

3. Il numero di inode si riferisce sempre ad un inode nello stesso filesystem, non è possibile che una directory contenga riferimenti ad inode relativi ad altri filesystem. 4. Quando si cambia nome ad un file senza cambiare filesystem, il contenuto del file non viene spostato fisicamente, ma viene semplicemente creata una nuova voce per l’inode in questione e rimossa la vecchia. 5. Gli inode dei file, che contengono i metadati ed i blocchi di spazio disco, che contengono i dati, sono risorse indipendenti ed in genere vengono gestite come tali anche dai diversi filesystem; è pertanto possibile sia esaurire lo spazio disco che lo spazio per gli inode, nel primo caso non sarà possibile allocare ulteriore spazio, ma si potranno creare file vuoti, nel secondo non si potranno creare nuovi file, ma si potranno estendere quelli che ci sono. I file non hanno nome negli inode. La numerazioni degli inode è unica in ogni filesystem.

Data

Descrizione

ACCESS MODIFY CHANGE

Ultima data di accesso al file Data in cui vi è stata una modifica al contenuto del file Data in cui vi è stata una modifica ai metadati del file

Comando

Descrizione

ls -li stat -x nomefile apropos contents

Mostra il numero di inode di ogni file Mostra informazioni sul file contenuti nell’inode.33 Esegui una ricerca nel manuale di sistema per la parola “contents”34

Iterazioni e cicli Ciclo infinito Se eseguiamo il comando seguente, provocheremo un ciclo infinito, poiché il comando true35 non sarà mai falso. Il comando che usa l’istruzione di iterazione while, dopo aver verificato la condizione d’iterazione, eseguirà il comando date che manderà in output la data corrente, attenderà per una pausa di un secondo e ripeterà il ciclo, valutando nuovamente la condizione d’iterazione. while true; do date; sleep 1; done Per interrompere il comando, premere la combinazione di tasti CTRL+D dalla tastiera. Altri cicli for aaa in 1 3 67 890 > do > echo $(($aaa * 2) > done for ((a=1;a<15:a++)); do echo $a; done

Il nome del file non è contenuto nell’inode Comando apropos - http://man.cx/apropos 35 Comando true - http://man.cx/true 33 34


15

Calcolatore Comando

Descrizione

bc scale=4 scale=40 7/3

Calcolatore36 Restituirà il risultato approssimato a 4 cifre decimali Restituirà il risultato approssimato a 40 cifre decimali Restituirà “2,3333”37

Stdin, Stdout, Stderr Lo standard error (stderr) e lo standard output (stdout) per default sono inviati al terminale. Ad ognuno di questi stream38 standard corrisponde un numero, grazie al quale è possibile reindirizzarne il canale predefinito, ad esempio per scrivere all’interno di un file.

Codice

Stream

0 1 2

Stdin - Standard Input (default: Tastiera) Stdout - Standard Output (default: Terminale) Stderr - Standard Error (default: Terminale)

Ad esempio: ls * 1> nomefile Ridirige l’output del comando ls * in un file denominato “nomefile”. ls nome_file_non_esistente 2> errore Eseguendo il comando ls su un file che non esiste e reindirizzando lo standard error in un file denominato “errore”, troveremo un messaggio di errore simile al seguente: Such file does not exist

Altri comandi Comando

Descrizione

tty cat > /dev/ttys000 /dev/null cat /dev/random40 > nomefile head nomefile head -30 nomefile head -3 nomefile tail nomefile

Vedi il terminale utilizzato al momento Ridirige l’input su un altro terminale File speciale che elimina tutto ciò che riceve39 Scrive bit a caso in un file (per bloccare CTRL+D) Vedi le prime 10 righe del file “nomefile”41 Vedi le prime 30 righe del file “nomefile” Vedi le prime 3 righe del file “nomefile” Vedi le ultime 10 righe del file “nomefile”42

Utilità calcolatore - http://man.cx/bc Se prima si applicherà il comando scale=4 38 Panoramica sugli Standard stream - http://en.wikipedia.org/wiki/Standard_streams 39 The Null Device - http://en.wikipedia.org/wiki//dev/null 40 Random Number Generator - http://en.wikipedia.org/wiki//dev/random 41 Comando Head - http://man.cx/head 36 37


16

Il comando mostra la riga 25 del file indicato: head -25 nomefile.txt | tail -1 Il seguente comando mostra la riga 25 del file indicato e visualizza anche il numero di riga: cat -n nomefile.txt | head -25 | tail -1

Il seguente file contiene tutte le parole della lingua inglese, per aprirlo con TextWrangler scrivere: edit usr/share/dict/words

Comando

Descrizione

system_profiler basename nomedirectory basename $(pwd) stat -f%i nomedirectory stat -c%i * stat -c%Y * OPTION+F5

Visualizza le informazioni di sistema (MacOS X)43 Restituisce il nome della directory44 Restituisce il nome della directory attuale Restituisce l’inode della directory “nomedirectory” (MacOS X) Restituisce gli inode di tutti i file di quella directory (GNU/Linux) Vedi le date45 di tutti i file della directory corrente ~ (Tilde)

Cercare file Il comando find46 consente di cercare file all’interno di una directory, sulla base di un criterio, segue la sintassi generica del comando. find directory criterio Ad esempio il seguente comando cerca all’interno della cartella home dell’utente (~), utilizzando la ricerca per nome, il file di nome “nomefile”. find ~ -name nomefile Mentre il seguente comando restituisce tutti i file e le cartelle che si chiamano dir*: find ~ -name dir\*47 Il seguente comando stampa a video i risultati della ricerca (anche se find lo fa di default) find ~ -name dir\* -print

42 43

Comando Tail - http://en.wikipedia.org/wiki/Tail_(Unix) Comando system_profiler -

https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/system_profiler.8.html

Comando basename - http://man.cx/basename Le date sono espresse in secondi a partire dal 01/01/1970 (Epoch) 46 Comando find - http://man.cx/find 47 Il carattere * è stato preceduto da uno backslash \ per evitare la pathname expansion della shell 44 45


17

Il seguente comando filtra i risultati per tipo di file # cerca solo i file find ~ -name dir\* -type f # cerca solo le cartelle find ~ -name dir\* -type d È possibile combinare le ricerche, imponendo una condizione OR tra i tipi: find ~ -name dir\* \(-type f -o -type d\) -print Nell’esempio seguente, il comando cercherà i file di 102 byte. find ~ -size 102c Altri esempi: find ~ -name dir\* -type f -exec file {} \; find ~ -size -100c -exec stat -c%s \; 2> /dev/null find ~ -size -100c -size +50c -exec stat -f%z {} ; 2> /dev/null

Script Costruire uno script che prenda come argomento il nome di una directory e faccia la somma delle dimensioni in byte dei file in essa contenuti. #!/bin/bash if[ $(uname) == Darwin ] then find $* -type f -exec stat -f%z {} \; 2>/dev/null | tr \\n + echo 0 elif[ $(uname) == Linux ] find $* -type f -exec stat -c%s {} \; 2>/dev/null | tr \\n + echo 0 then echo Che sistema operativo utilizzi? fi | bc echo '$* = ' $* Il comando principale del nostro script sarà: find $* -type f -exec stat -f%z {} \; Che si occuperà (in ambiente MacOS X) di trovare tutti i file nella cartella. Il comando tr48 si occuperà della trasformazione gli ‘a capo’ (newline) in un +. tr \\n + 48

Translate Characters - http://man.cx/tr


18

Oppure nell’esempio seguente, trasformiamo tutti i caratteri di ‘:’ in uno spazio bianco: echo $PATH | tr :\ ' '

Utilizzo del comando grep Cercare la stringa “inu” all’interno di un file denominato “sommabytes.sh” grep inu sommabytes.sh Cercare la stringa “inu” all’interno del file del dizionario: grep inu /usr/share/dict/words Cercare la stringa “inu” in tutti I file della directory corrente: grep -r inu . Copiare un file da un computer remoto al pc locale, ad esempio il file del dizionario italiano scp nomeutente@dominio.tld:/usr/share/dict/italian .

grep [abc]...[xyz] italian

Simbolo

Descrizione

^

Caret - Inizio riga (All’interno delle Square Brackets assume un significato diverso) A fine stringa, indica la fine della parola

$

grep '^[abc]...[xyz]' italian grep '^[abc]...[xyz]$' italian Cercare nel file indicato le parole che iniziano per “r” e che terminano per “sa” e che abbiano 3 caratteri tra inizio e fine parola: grep '^r...sa$' /Users/Name/Desktop/italian Cercare nel file indicato tutte le parole che contengono almeno tre vocali di seguito: grep -E '[^aeiou]{3,}' italian Cercare le parole che contengono almeno 5 vocali di seguito: grep -E '[^aeiou]{5,}' italian Per le parole che contengono solo 5 vocali di seguito: grep -E '[^aeiou]{5}' italian


19

Parameter Expansion49 Definire una variabile “a” e visualizzare il suo valore a terminale: a=10 echo $a Concatenare al valore di “a” un numero: echo ${a}4 Se il “parameter” è non impostato o nullo, l’espansione di “word” è sostituita. Altrimenti è “parameter” manterrà il suo valore: ${parameter:-word} Se il “parameter” è non impostato o nullo, assegna a “parameter” il valore di “word”: ${parameter:=word} Se il “parameter” non è impostato o è nullo, l’espansione di “word” (oppure un messaggio che informa della non esistenza di “word”) è scritto nello standard error e la shell, se non interattiva, termina. Altrimenti viene mantenuto il valore di “parameter”: ${parameter:?word} Se il “parameter” non è impostato o è nullo, non verrà modificato, altrimenti, sostituirà il valore del parametro con l’espansione di “word”: ${parameter:+word} Definisci un offset: ${parameter:offset} ${parameter:offset:lunghezza} Ad esempio: a=ABCDEFGHIL echo $a echo ${a:4} echo ${a:4:3}

Visualizzerà: ABCDEFGHIL Visualizzerà: EFGHIL Visualizzerà: EFG

Il comando seguente restituisce la lunghezza della stringa assegnata ad una variabile: echo ${#a}

49

Bash Expansions - http://man.cx/bash#heading14


20

Trova la stringa “CDE” e la sostituisce con “123”. Attenzione! Il valore di “a” non cambia. Sarà sostituita solo la prima occorrenza: echo ${a/CDE/123} Per effettuare la sostituzione in tutte le occorrenze: echo ${a//CDE/123} Per eliminare il match più corto del “pattern”: ${parameter#pattern} Per eliminare il match più lungo: ${parameter##pattern}

Date ed orari I comandi presentati di seguito mostrano una serie di utilizzi e di formattazione della data.

Comando

Descrizione/Risultato

date date +%A date +%h date +%H date +%H%M%S date +%H:%M:%S date "+%H:%M:%S $a" date +%Y date +%Y%m%d%H%M%S cal cal anno cal 2012

Thu Apr 12 16:10:00 CEST 2012 - Data completa Mostra il nome completo del giorno della settimana: es. Thursday Mostra il mese Mostra l’ora Visualizza ore, minuti e secondi, senza separatori: es. 085012 Visualizza ore, minuti e secondi con separatori: es. 08:50:12 Visualizza l’orario completo ed il valore della variabile “a” Visualizza l’anno 20120412162016 - visualizza data ed ora complete, senza separatori Visualizza il calendario del mese corrente Visualizza il calendario dell’anno indicato Visualizza il calendario dell’anno 2012

Per visualizzare la data attuale completa, formattata, eseguire: date "+%d/%m/%Y %H:%M:%S" che restituirà un output simile al seguente: 12/04/2012 16:21:16


21

Script Costruire uno script che prenda come argomento una directory e tolga gli spazi dai nomi dei file in essa contenuti. Innanzitutto creare una cartella e creare al suo interno una serie di file che contengano spazi all’interno del nome: mkdir nomecartella cd nomecartella touch file\ 001 file\ 002 file\ 003 file\ 004 file\ 005 Il comando che elimina gli spazi può essere semplificato ad una singola riga: for i in *; do mv "$i" ${i/Nome con spazio/NomeSenzaSpazio}; done Tuttavia il comando precedente lavorerà esclusivamente con i file che abbiano come nome il pattern indicato nel comando stesso, nell’esempio “Nome con spazio”. Anche con il comando “tr50” è possibile eliminare gli spazi: touch "gita al mare"005 echo gita\ al\ mare005 | tr -d ' ' Segue lo script completo per l’eliminazione degli spazi dai nomi dei file: “stripspaces.sh” #!/bin/bash cd $1 for FILE in * do FILE_NEW=$(echo "$FILE" | tr -d ' ') mv $FILE_NEW done Per sostituire gli spazi con un underscore, il comando “tr” deve essere così strutturato: tr ' ' '_' Il medesimo script per non considerare le directory, diventerà: #!/bin/bash cd $1 for FILE in * do if [-f "$FILE" ]; then FILE_NEW=$(echo "$FILE" | tr ' ' '_') mv "$FILE" $FILE_NEW fi done 50

Comando Translate Characters - http://man.cx/tr


22

Array Assegnamento di un valore agli elementi 0, 1 e 2 del vettore “a”: a[0]=5 a[1]=5 a[2]=6 Il comando seguente visualizzerà il vettore utilizzando un ciclo: for i in 0 1 2 3 4 5 6; do echo elemento $i = ${a[$i]}; done Una scrittura alternativa del comando è la seguente: for i in 0 1 2 3 4 5 6; do echo elemento $i = ${a[i]}; done Per visualizzare la lunghezza dell’array (saranno conteggiati esclusivamente gli elementi non nulli): echo ${#a[*]} È possibile creare e popolare un array “b” come di seguito: b=(1 34 56 78 98 34 56 23 12) È possibile popolare un array con l’output di un comando, ad esempio: c=($(cat italian)) echo ${#c[*]}

Italian è il file del dizionario Restituirà 116878

Valori casuali Comando

Descrizione/Risultato

echo $RANDOM echo $((15%4)) echo $((RANDOM*RANDOM%116878))

Genera un numero casuale Operazione “Modulo” Genera e moltiplica fra loro due numeri casuali, successivamente esegue l’operazione modulo del numero ottenuto per 116878.

Costruire uno script che generi parole casuali dal dizionario Italiano: “iching.sh” #!/bin/bash c=($(cat /path/Documents/italian)) echo ${c[RANDOM]} ${c[RANDOM]} ${c[RANDOM]} ${c[RANDOM]} ${c[RANDOM]} \ ${c[RANDOM]} ${c[RANDOM]}


23

Costruire uno script che estragga casualmente 7 parole dal dizionario inglese, le visualizzi a terminale e le legga. “iching2.sh” #!/bin/bash c=($(cat /usr/share/dict/words)) LUNGH=${#c[*]} a="${c[$((RANDOM*RANDOM%LUNGH))]} ${c[$((RANDOM*RANDOM%LUNGH))]} ${c[$((RANDOM*RANDOM%LUNGH))]} ${c[$((RANDOM*RANDOM%LUNGH))]}

\ ${c[$((RANDOM*RANDOM%LUNGH))]} ${c[$((RANDOM*RANDOM%LUNGH))]} ${c[$((RANDOM*RANDOM%LUNGH))]}"

echo $a say $a

Ulteriori informazioni sui processi Comando

Descrizione

ps tty id id root ps -e ps -f ps -ef

Visualizza i processi che utilizzano terminali Visualizza il terminale attualmente utilizzato Visualizza l’ID dell’utente corrente sulla macchina Visualizza l’ID utente di root Visualizza tutti i processi (anche senza terminali) anche di altri utenti Vedi l’User ID (UID) Visualizza i processi applicando una specifica formattazione Colonne UID (User ID) e PID (Process ID) (Linux) visualizza l’albero dei processi Visualizza il Process ID del bash in esecuzione

pstree echo $$

Con il comando ps -ef i dati verranno formattati in tre colonne: UID

PID

User ID

Process ID

PPID Parent Process ID

Ad ogni file sono assegnati 12 permessi totali, infatti oltre ai classici 9 bit dei permessi del proprietario, del gruppo e degli altri (U.G.O), esistono 3 bit precedenti che consentono di eseguire il processo come se si stesse utilizzando un altro account. I 3 bit in questione sono i seguenti:

Bit

Descrizione

4 2 1

Set User ID bit Set Group ID bit Sticky bit

Se il bit Set User ID è impostato, quando esegue un file/processo, esso viene eseguito con l’identità del proprietario del file. Esiste infatti una differenza tra: Real User ID ID dell’utente che ha avviato il file eseguibile del processo

Effective User ID ID del proprietario del file che viene eseguito.


24

Se ad esempio si avvia il comando di cambio password, il file associato al processo è di proprietà della root, pertanto l’Effective User ID sarà quindi “root”. /usr/bin/passwd

È possibile personalizzare l’output del comando “Process Show” ps51 specificando i campi desiderati, come negli esempi seguenti:

Comando

Descrizione

ps -e -opid,comm ps -e -opid=XYZ,comm=KLM

Visualizza le colonne Process ID (PID) e il comando lanciato Visualizza le colonne PID e CMD personalizzandone le intestazioni Visualizza le colonne PID e CMD con le intestazioni vuote Visualizza le colonne PID, Real User ID, Effective User ID e CMD Visualizza la colonna relativa al tempo cumulativo di esecuzione del processo Visualizza l’UID del processo numero XXXXX

ps -e -opid=,comm= ps -e -opid,ruid,uid,comm -time ps -p XXXXX -ouid

L’opzione -o del comando ps consente di specificare il formato di output sotto il controllo dell’utente:

Comando

Descrizione

ps -e -opid,ruid,uid oppure ps -e -opid,ruser,user ps -e -opid=ID,uid=UTENTE

Visualizza le colonne Process ID (PID), la colonna Real User ID e la colonna Effective User ID (UID) di tutti i processi in esecuzione sulla macchina Visualizza PID e UID, personalizzando l’intestazione

È possibile creare un array che contenga tutti i PID dei processi attivi sul sistema: arraypid=($(ps -e -opid=)) echo ${#arraypid[*]} Per assegnare ad “a” il valore dell’User ID che esegue un dato processo: a=$(ps -p 92174 -ouid=) echo $a La visualizzazione dei processi può essere ulteriormente personalizzata come nell’esempio seguente: for i in $(echo ${arraypid[*]}) > do > echo processo $i eseguito da $(ps -p $i -ouid=) > done

51

Process Show - http://man.cx/ps


25

Costruire uno script che inserisca in due array differenti le informazioni relative ai processi attivi nel sistema, in particolare, nel primo array inserisca il PID e nel secondo inserisca l’UID e si crei una visualizzazione a terminale che faccia corrispondere gli elementi del primo array con quelli del secondo. #!/bin/bash # ****************************** # File: psindoublearray.sh # Function: Puts in two arrays data for all the processes in the system # primoarray=($(ps -e -opid=)) for ((i=0; i < ${#primoarray[*]}; i++)) do secondoarray[i]=$(ps -p ${primoarray[i]} -ouid=) done for ((i=0; i < ${#primoarray[*]}; i++)) do echo ${primoarray[i]}-----${secondoarray[i]} done Sostituendo nel secondo array l’UID con il Comando eseguito dal processo, si avrebbe #!/bin/bash # ****************************** # File: psindoublearray2.sh # Function: Puts in two arrays data for all the processes in the system # primoarray=($(ps -e -opid=)) for ((i=0; i < ${#primoarray[*]}; i++)) do secondoarray[i]=$(ps -p ${primoarray[i]} -comm=) done for ((i=0; i < ${#primoarray[*]}; i++)) do echo ${primoarray[i]}' <---> '${secondoarray[i]} done


26

Codifica Su un computer i caratteri dell’alfabeto sono “codificati” come numeri al fine di facilitare la memorizzazione di un testo o la sua trasmissione attraverso le reti. Esistono una lunga serie di codifiche disponibili, le più diffuse sono: ASCII52 e Unicode53. ASCII è un sistema di codifica dei caratteri a 7 bit, comunemente utilizzato nei calcolatori, ideato nel 1961 e divenuto standard ISO 646. Alla specifica iniziale basata su codici 7 bit, negli anni successivi, fecero seguito una serie di estensioni ad 8 bit con lo scopo di aumentare il numero di caratteri rappresentabili, includendo le vocali accentate e altri simboli (Extended ASCII54). Unicode è un sistema di codifica che assegna un numero univoco ad ogni carattere usato per la scrittura dei testi, in modo indipendente dalla lingua, dalla piattaforma e dal programma utilizzati. Il codice assegnato al carattere viene rappresentato con U+, seguito dalle 4 (o 6) cifre esadecimale del numero che lo individua. Unicode incorpora lo standard ISO/IEC 8859-1 e codifica i caratteri utilizzati in quasi tutte le lingue, nonché simboli matematici, chimici, cartografici, l’alfabeto Braille, ideogrammi e altri simboli. UTF-855 è una codifica di caratteri Unicode in sequenze di lunghezza variabile di byte, creata da Rob Pike e Ken Thompson. UTF-8 utilizza da 1 a 4 byte rappresentare un carattere Unicode. Un solo byte è necessario per rappresentare i 128 caratteri dell’alfabeto ASCII (posizioni Unicode da U+0000 a U+007F).

Comando

Descrizione

hexdump file hexdump -c file

Visualizza il file indicato nel formato specificato dall’utente56 Visualizza il file specificato in esadecimale, 16 caratteri per riga, in 3 colonne separate da spazi.

Una tabella dei caratteri UTF-8 può essere trovata alla pagina web: http://www.utf8-chartable.de/ I diversi sistemi operativi rappresentano in modo differente la fine di una riga di testo (newline). Il simbolo di newline57 non è un carattere visibile sullo schermo .

Rappresentazione

Sistema Operativo

LF CR CR+LF

Unix / Unix-like, GNU/Linux, MacOS X, FreeBSD MacOS (fino alla versione 9) Microsoft Windows, DOS, Symbian OS, Palm

In Unicode tali simboli sono rappresentabili:

Simbolo

Descrizione

Unicode

LF CR CR+LF

Line Feed Carriage Return Carriage Return + Line Feed

U+000A U+000D U+000D U+000A

52American

Standard Code for Information Interchange - http://it.wikipedia.org/wiki/ASCII Unicode - http://it.wikipedia.org/wiki/Unicode - http://www.unicode.org/ 54 Extended ASCII (ISO 8859) - http://it.wikipedia.org/wiki/ISO_8859 55 UTF-8 (Unicode Transformation Format - 8 bit) - http://it.wikipedia.org/wiki/UTF-8 56 Comando hexdump - http://man.cx/hexdump 57 Newline - http://en.wikipedia.org/wiki/Newline 53


27

Conversioni tra codifiche È possibile modificare la codifica di un file utilizzando il comando iconv58 iconv [-f encoding] [-t encoding] [file] Per visualizzare tutti i formati disponibili: iconv -l Oppure per convertire il file dalla codifica ISO Latin1 alla codifica UTF-8: iconv -f L1 -t UTF-8 testo-ISOLatin1.txt Dove L1 identifica la codifica ISO Latin1. È possibile convertire la codifica di un file e salvarne il contenuto in un nuovo file: iconv -f L1 -t UTF-8 italian_linux.txt > italian_linux_utf8.txt

È disponibile online un file di testo in formato UTF-8 che dimostra le potenzialità di questa codifica: http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt

Job Control59 di Bash Bash consente di lanciare un job e di metterlo in background in modo tale da poter continuare ad utilizzare il terminale per eseguire altri jobs, che quindi sono eseguiti in foreground. Per lanciare un job e porlo in background: find / -name asdsa 2>/dev/null & Il simbolo “&” al termine del comando, pone il job lanciato, nell’esempio “find” in background.

Comando

Descrizione

jobs CTRL+Z (^Z) fg %1 bg fg

Vedi tutti i jobs attivi Interrompe il comando Poni in foreground il processo 1 Continua il job in background Continua il job in foreground

Lo standard input è di solito indirizzato al job in foreground.

58 59

Iconv - codeset conversion - http://man.cx/iconv Job Control - http://man.cx/bash#heading26


28

Personalizzazione della shell, gli alias e le funzioni Il file .bash_profile è uno “startup-file” di bash, esso contiene delle informazioni e delle configurazioni personalizzabili di bash. Per visualizzarne il contenuto:

cat .bash_profile Una shell di login60 (cioè associata alla finestra) è rappresentata in “ps” (Process Show) con un trattino (hyphen) davanti al nome. Ad esempio: -bash È possibile modificare alcune opzioni della shell, modificando il file .bash_profile Ad esempio, per personalizzare l’inizio di ogni riga del prompt61: PS1="\t -> " È inoltre possibile definire degli alias per alcuni comandi, sempre nel file .bash_profile alias ll='ls-la' Nell’esempio sopra, è stato creato un alias per il comando ls-la che potrà essere lanciato scrivendo ll. Gli alias possono essere definiti anche utilizzando le funzioni. La funzione seguente definisce il comando pman che consente di ottenere una versione stampabile in formato PostScript/PDF della pagina di manuale relativa al comando fornito come argomento, inoltre apre nell’applicazione Anteprima di MacOS X, il file creato. pman() { man -t "${1}" | open -f -a /Applications/Preview.app }

Comando

Descrizione

pman bash pman open

Apre in formato PostScript il manuale di bash Apre in formato PostScript il manuale di open

La funzione seguente definisce un alias per il comando ls applicato sulla home directory dell’utente. casa() { ls ~ } In .bash_profile è possibile includere un altro file scrivendo: source .bashrc

60 61

http://man.cx/bash#heading7 http://man.cx/bash#heading27

oppure

. .bashrc


29

Il comando seguente funziona esclusivamente per il primo file: find . -type f -name asy\* | stat -x Mentre utilizzando xargs62 passa come argomenti tutti i file restituiti dal primo comando: find . -type f -name asy\* | xargs stat -x Eventuali spazi nei nomi dei file possono creare problemi. Per evitare tali problemi, è possibile separare mediante un carattere NULL i risultati del comando find. find . -type f -name asy\* print0 Quindi il comando completo diventa: find . -type f -name asy\* print0 | xargs -0 stat-x

Crittografia È possibile crittografare del testo, oppure il contenuto dei file utilizzando differenti algoritmi.

Comando

Descrizione

md5

Codifica restituendo un digest composto da 32 caratteri alfanumerici (solo lettere e numeri) Restituisce il digest dei file contenuti nella directory corrente Mostra solo gli md5 Restituisce l’hash md5 relativo al file

md5 * md5 -q * md5 nomefile

Su Linux il comando analogo è md5sum:

Comando

Descrizione

md5sum * md5 * 2>/dev/null

Restituisce il digest dei file contenuti nella directory corrente Restituisce il digest dei file contenuti nella directory corrente e ridireziona l’output.

Il comando: echo andiamo a mangiare un gelato | md5 Restituirà l’hash md5 del contenuto del comando echo. Il comando seguente verificherà le differenze tra i file forniti come argomento: diff nomefile1 nomefile2 Esiste un ulteriore comando per la crittografia in diversi formati: openssl dgst -md5 nomefile.txt openssl dgst -sha1 italian_linux.txt 62

http://man.cx/xargs

Restituisce l’hash md5 del file Restituisce l’hash sha1 del file


30

È possibile crittografare/decrittare il contenuto di un file e salvarlo in un file: openssl enc -des3 < italian_linux_utf8.txt > italian_linux_enc openssl enc -des3 -d < italian_linux_enc L’attributo -d nell’ultimo comando indica che si tratta di una decodifica.

Scope delle variabili Una variabile definita in bash non sarà conosciuta da un bash interno ad esso. a=5 echo $a bash echo $a

La variabile a vale 5 Aprendo un bash interno al bash principale La variabile a non sarà conosciuta

Per esportare una variabile in shell interne è necessario utilizzare il comando export a=5 echo $a export a bash echo $a

La variabile a vale 5 Esporta il valore della variabile alle altre shell Aprendo un bash interno al bash principale La variabile a vale 5

Il comando export funziona con i livelli inferiori, cioè se uso il comando export su una variabile definita in un bash di secondo livello, tale variabile sarà conosciuta dai livelli inferiori (3°, 4°, 5°, ecc.), ma non sarà conosciuta dal bash di 1° livello. Le modifiche apportare alle variabili nei livelli inferiori, non saranno applicate ai livelli superiori. echo $SHLVL

Restituisce il livello di shell su cui si sta operando

Hard Link & Soft Link Soft Link63 Si dice collegamento simbolico (o Link Simbolico / Symlink / Soft link) un particolare tipo di file che è un rimando ad un altro file o directory. Un link simbolico è un file contenente un percorso relativo o assoluto al file o directory a cui fa riferimento; questo permette di creare collegamenti non solo all’interno della stessa partizione, ma anche da un file system ad un altro, offrendo più flessibilità rispetto ad un collegamento fisico. La flessibilità si trasforma in minore affidabilità in quanto, se il file a cui punta viene rimosso o cambiato di nome, il collegamento rimane orfano. Per creare un link simbolico si usa il comando ln ln -s nomefile nomelink Il soft link sarà rappresentato dal comando ls: ls -la nom*

63

nomelink -> nomefile

Soft link - http://it.wikipedia.org/wiki/Collegamento_simbolico


31

Hard Link64 Si dice collegamento fisico (hard link) l’associazione del nome di un file al suo contenuto. Un collegamento fisico fa riferimento ai dati (il contenuto) di un file, e in ciò si differenzia dai collegamenti simbolici che fanno riferimento a nomi di file. Un’altra differenza è che il collegamento fisico deve trovarsi sullo stesso file system che contiene i dati a cui fa riferimento, e che un collegamento fisico non può restare orfano. Per ogni file o directory nei sistemi Unix il file system mantiene un identificativo univoco (inode) ed un conteggio degli hard link che vi fanno riferimento. Un hard link contiene semplicemente il nome ed il riferimento all’inode del file, senza altre informazioni. L’eliminazione di un file (cioè di un suo collegamento fisico) non implica l’annullamento di tutti i collegamenti fisici ad esso, perché ogni hard link è indipendente. Lo spazio occupato dai dati può essere liberato solo quando il conteggio degli hard link di un file diventa zero. Per creare un link simbolico si usa il comando ln ln nomefile nomelink Le directory hanno sempre gemelli (cioè hard link che le puntano) poiché sono referenziate dalle directory figlie e dalla directory parent.

Comando

Descrizione

echo $SECONDS echo $COLUMNS COLUMNS=70 ./nomescript

Tempo, in secondi, dall’avvio della shell Visualizza il numero delle colonne della shell attiva Imposta il numero delle colonne a 70 per eseguire lo script indicato

Operazioni matematiche bc 4/3 scale=10 4/3 scale=4 4/3 bc -l s(5) s(x) c(x) a(x) l(x) e(x) echo 4/3 | bc echo 4/3 | bc -l echo 'scale=5;4/3' | bc

64

Apre un ambiente matematico Restituirà 1 Utilizza un’approssimazione a 10 cifre decimali Restituirà 1,3333333333 Utilizza un’approssimazione a 4 cifre decimali Restituirà 1,3333 Carica la libreria standard delle funzioni matematiche sin(5) = -.958… rad sin(x) cos(x) arctan(x) logaritmo(x) esponenziale(x) Restituirà 1 Restituirà 1,333… approssimato a 20 cifre decimali Restituirà 1,33333

Hard Link - http://it.wikipedia.org/wiki/Collegamento_fisico


32

Browser da riga di comando È possibile visualizzare in versione testuale siti internet e pagine web utilizzando il browser da riga di comando Lynx65. È possibile scaricare l’ultima versione di Lynx dal sito ufficiale del progetto66. Per visitare ad esempio, il sito www.repubblica.it, si scriverà il seguente comando nel terminale: lynx http://www.repubblica.it Per scaricare la pagina web contenente il testo completo della Divina Commedia: lynx -dump http://www.filosofico.net/ladivinacommedia.htm

Esercizio Trovare la parola più utilizzata nella Divina Commedia. Innanzitutto è necessario scaricare il testo completo della Divina Commedia in un file di testo. lynx -dump http://www.filosofico.net/ladivinacommedia.htm Si procede con l’eventuale modifica della codifica del documento, per evitare problemi di interpretazione delle lettere accentate e di altri simboli, conviene convertire il documento nel formato UTF-8. Successivamente è necessario sostituire gli spazi tra le parole con un newline (a capo). cat divina_utf8.txt | tr ' ' '\n' Tuttavia sarebbe opportune eliminare dal testo anche i simboli di interpunzione: cat divina_utf8.txt | tr ' ,.;?-:«»()' '\n' È possibile eliminare tutti i segni di interpunzione direttamente tramite uno specifico argomento del comando tr. L’esercizio chiede di trovare la parola più utilizzata nel testo, pertanto dopo la “pulitura” del testo, si procederà ad un primo ordinamento alfabetico ed all’eliminazione dei doppioni (un’opzione del comando uniq conterà le occorrenze di ogni parola), in seguito si applicherà un ordinamento numerico (l’opzione nr del comando sort) e si applicherà la paginazione al risultato. Il comando completo sarà analogo al seguente: cat divina_utf8.txt | tr [:punct:] '\n' | tr ' ' '\n' | sort | uniq -c | sort -nr | less

65 66

Lynx - http://it.wikipedia.org/wiki/Lynx_(software) Lynx Browser - http://lynx.isc.org/current/


33

Esercizi 

Costruire uno script che disegni verticalmente una sinusoide continua la cui frequenza viene fornita come parametro.

#!/bin/bash if [ $# -ne 1 ]; then echo 'Usage export COLUMNS; ./sinusoide.sh frequenza'; exit; fi if [ -z $COLUMNS ]; then echo 'Usage: export COLUMNS; ./sinusoide.sh frequenza'; exit; fi ampiezza=$(( COLUMNS/2 )) frequenza=$1 t=0; while true; do b=$(echo "c=$ampiezza*s($frequenza*$t*3.14/180);scale=0; $ampiezza + c/1" | bc -l); for (( a = 1; a < b; a++ )); do echo -n " "; done; echo '*'; ((t++)) done 

Costruire uno script che stampi la percentuale della CPU utilizzata dal comando del quale viene fornito il PID.

#!/bin/bash pid=$1 #scale=${2:-2} # this line is an alternative to the following echo ${scale:=2} > /dev/null while true; do cpu=$(ps -p $pid -o%cpu= | tr , .) sleep 0.05 b=$(echo "c=$scale*$cpu;scale=0; c/1" | bc -l); for (( a = 1; a < b; a++ )); do echo -n "-"; done; echo '*'; done


34

Ulteriori informazioni sui processi Quando si lancia un comando, avvengono due fasi: 1. FORK67: bash si duplica, copia variabili, stato della memoria 2. EXEC68: prende come argomento il file eseguibile sul disco, lo esegue, prende i dati (variabili, ecc) del file eseguibile. È possibile trasformare il bash corrente nel comando indicato, inserendo un comando analogo al seguente: exec nomecomando Ad esempio “ls”: exec ls Esistono due tipi di comandi:  COMANDI SU DISCO  SHELL BUILTIN I comandi su disco prevedono la creazione di un processo mediante fork ed exec. Un comando builtin viene eseguito direttamente da bash. È possibile verificare se un comando è dell’uno o dell’altro tipo, utilizzando il comando type: which echo type echo type cp type sleep

/bin/echo echo is a shell builtin cp is /bin/cp sleep is /bin/sleep

Il comando type restituirà il percorso del file eseguibile, qualora si tratti di un comando su disco. Quando un processo parte ha una sua memoria (virtuale), ogni processo è convinto di avere a disposizione il massimo della memoria indirizzabile. In un sistema a 32 bit, la memoria totale indirizzabile è 232, cioè 4 GB. Lo swapping 69consiste nell’utilizzo di spazio su disco come spazio temporaneo per la memoria dei processi non attivi. Una rappresentazione della memoria:70

Fork: http://en.wikipedia.org/wiki/Fork_(operating_system) Exec: http://en.wikipedia.org/wiki/Exec_(operating_system) 69 Swap: http://it.wikipedia.org/wiki/Swap_(informatica) 70 GaPiL - pg. 25 - http://gapil.gnulinux.it/files/2011/12/gapil.pdf 67 68


35

Comando

Descrizione

vmmap vmmap $$

Virtual Memory Map Virtual Memory Map di Bash

Alcuni comandi su Linux cd /proc cat cpuinfo ls cd $$ ls -lad cwd cat environ cat maps

Process information pseudo-filesystem71 Visualizza informazioni sulla CPU Visualizza i file presenti nella cartella /proc Vai alla directory corrispondente al bash Informazioni sulla Current Working Directory Variabili d’ambiente associate al processo corrente Visualizza una mappa della memoria

Comando

Descrizione

free pmap PID pmap $$ ldd /bin/bash

Visualizza lo stato della memoria (Totale/Utilizzata/Libera) Librerie utilizzate da un processo (funziona solo a runtime) Librerie utilizzate dal processo Bash Visualizza le dipendenze di un processo72 (anche a processo non avviato) Visualizza le dimensioni Visualizza lo stato della memoria virtuale Funzione simile alla printf del linguaggio C73

size /bin/bash vmstat printf

Esistono directory che hanno lo sticky bit, esso è necessario in cartelle utilizzate da molti utenti affinché ogni utente possa cancellare i propri file e non quelli degli altri. Per trovare le cartelle che hanno impostato lo sticky bit, eseguiamo il comando: find / -type d -perm +1000 2>/dev/null Le directory hanno inoltre il privilegio di esecuzione: tale permesso è denominato search bit, in quanto consente di accedervi per ricercare file. Per verificare, eseguire il comando: ls -lad nomecartella

Comando

Descrizione

du . du nomefile gzip -r nomecartella gunzip

Disk Usage - Cartella corrente Disk usage - File indicato, se il file è vuoto occupa 0 blocchi su disco Comprimi la cartella indicata74 Decomprimi

http://it.wikipedia.org/wiki/Procfs Shared Library Dependencies - http://man.cx/ldd 73 http://man.cx/printf 74 Comandi gzip e gunzip : http://man.cx/gzip 71 72


36

Altri comandi Comando

Descrizione

nice nomeprogramma exec nomeprogramma exec ls 1>filetemp.txt

Il comando abbassa la priorità del processo Sostituisce allo shell in uso lo script lanciato con il comando Sostituisce allo shell il comando ls il cui output viene salvato in filetemp.txt

Per trovare tutti i softlink presenti in home si esegue: find ~ -type l | less Il comando seguente restituisce il percorso del file a cui punta il softlink: readlink "/percorso/cartella/nomelink"

Segnali I segnali sono “Software Interrupt”, cioè un segnale appunto o un messaggio che avvisa circa il verificarsi di un certo evento. Esistono due tipi di segnali75: sincroni e asincroni. Quando ad esempio un utente preme la combinazione di tasti CTRL-C viene generato un segnale che forza l’interruzione di un processo. Il kernel invia al processo un segnale, il processo, una volta ricevuto il segnale può scegliere uno dei tre comportamenti disponibili:  DEFAULT: generalmente “terminate process”  IGNORARE IL SEGNALE: il segnale viene quindi ignorato ed il processo continua l’esecuzione  GESTIRE IL SEGNALE: il processo gestisce il segnale mediante un Signal Handler Il segnale 17 non può essere gestito [SIGSTOP].

Gestire i segnali È possibile gestire i segnali mediante il comando trap del quale segue la formattazione: trap [-lp] [arg] [sispec ...] Il comando arg è da leggere e da eseguire quando la shell riceve il segnale sigspec. Se arg è assente oppure -, tutti gli specifici segnali sono reimpostati ai loro valori originali (i valori che avevano precedentemente all’ingresso nella shell). Se arg è la stringa nulla il segnale specificato da ogni sigspec è ignorato dalla shell e dal comando che invoca. Se arg non è presente ed è fornito -p, i comandi trap associati con ogni sigspec sono visualizzati. Se non vengono forniti argomenti o se è dato solo -p, trap stampa la lista dei comandi associati con ogni numero di segnale. 76

Comando

Descrizione

trap ls SIGINT

Ad ogni segnale SIGINT (che si genera premendo CTRL-C) esegue il comando ls Visualizza tutti i segnali gestiti Annulla le impostazioni definite per il segnale SIGINT Visualizza i limiti della macchina in uso

trap -p trap - SIGINT ulimit -a 75 76

Segnali: http://it.wikipedia.org/wiki/Segnale_(informatica) Comando trap - Manuale di Bash: - http://man.cx/bash#heading31


37

Segue una tabella dei segnali: Signal

Description

SIGABRT SIGALRM SIGBUS

Process aborted Signal raised by alarm Bus error: "access to undefined portion of memory object" Child process terminated, stopped (or continued*) Continue if stopped Floating point exception: "erroneous arithmetic operation" Hangup Illegal instruction Interrupt Kill (terminate immediately) Write to pipe with no one reading Pollable event Profiling timer expired Quit and dump core Segmentation violation Stop executing temporarily Bad syscall Termination (request to terminate) Trace/breakpoint trap Terminal stop signal Background process attempting to read from tty ("in") Background process attempting to write to tty ("out") Urgent data available on socket User-defined 1 User-defined 2 Signal raised by timer counting virtual time: "virtual timer expired" CPU time limit exceeded File size limit exceeded

SIGCHLD SIGCONT SIGFPE SIGHUP SIGILL SIGINT SIGKILL SIGPIPE SIGPOLL SIGPROF SIGQUIT SIGSEGV SIGSTOP SIGSYS SIGTERM SIGTRAP SIGTSTP SIGTTIN SIGTTOU SIGURG SIGUSR1 SIGUSR2 SIGVTALRM SIGXCPU SIGXFSZ

Il segnale SIGSTOP stoppa il processo Il segnale SIGCONT riprende il processo

Segnale

Combinazione di tasti

SIGTSTP SIGQUIT SIGINT

CTRL-Z CTRL-\ CTRL-C

Signal number on Linux x86[1] 6 14 7 17 18 8 1 4 2 9 13 29 27 3 11 19 31 15 5 20 21 22 23 10 12 26 24 25


38

Il comando Kill Il comando kill77 serve per inviare segnali. Segue la sintassi del comando: kill [-s sigspec | -n signum | -sigspec ][pid | jobspec]... kill -l [sigspec | exit_status] Alcuni esempi: kill kill kill kill kill

-SIGINT PID -SIGINT 2264 -SIGKILL $$ -SIGSTOP 57348 -SIGCONT 57348

Invia Invia Invia Invia Invia

il il il il il

segnale segnale segnale segnale segnale

SIGINT al processo indicato SIGINT al processo 2264 SIGKILL (Termina) al bash corrente SIGSTOP (Stoppa) al processo 57348 SIGCONT (Riprendi) al processo 57348

Ricerca nel computer In MacOS X esiste un motore di ricerca integrato, denominato Spotlight78 che consente di effettuare ricerche approfondite tra i file presenti sul computer ed all’interno del contenuto dei file stessi. Spotlight dispone di un indicizzatore istantaneo. Esiste una versione del motore di ricerca, disponibile dalla riga di comando, il comando mdfind79

Comando

Descrizione

mdfind -0 mdfind -onlyin cartella mdfind -live mdls nomefile strings nomefile

Separa i risultati mediante NULL (per manipolarli con xargs) Restringe la ricerca ad una specifica cartella Il comando continua a girare, aggiorna i risultati in tempo reale Restituisce i metadati del file Visualizza le stringhe di un file binario

mdfind consente anche di eseguire ricerche in base ai metadati di un file. Il comando seguente cercherà tutti i file di immagine la cui altezza in pixel sarà inferiore a 500 pixel. mdfind 'KMDItemPixelHeight<500' Il comando seguente cercherà tutti I file di imagine la cui altezza in pixel è compresa tra 440 e 500 pixel: mdfind 'KMDItemPixelHeight<500 && KMDItemPixelHeight>440' Il comando seguente, uguale al precedente, manipolerà l’output restituendo l’altezza in pixel di ogni immagine trovata ed eseguirà un ordinamento dell’output. mdfind 'KMDItemPixelHeight<500 && KMDItemPixelHeight>440' | xargs -0 mdls -name\ KMDItemPixelHeiht | sort -n

Kill - Terminate or signal processes - http://man.cx/kill Apple Spotlight - http://en.wikipedia.org/wiki/Spotlight_(software) 79 Ulteriori informazioni su mdfind - http://macdevcenter.com/lpt/a/6403 77 78


39

Tubi a T È possibile costruire dei tubi “a T”, per estrarre il risultato di un comando, tra due pipe, così da poter manipolare il risultato “intermedio” dei comandi. Il comando tee serve per costruire questo tipo di tubi, come nell’esempio: ps -ef | tee uscitatubo.txt | grep bash

Altri comandi Sed è un linguaggio di scripting, un suo utilizzo interessante è la sostituzione di caratteri. echo casa | sed s/sa/ma

Restituirà “cama”, sostituirà la sillaba “sa” con “ma”

Il comando jot genera una serie di dati sequenziali o casuali.

Comando

Descrizione

jot jot jot jot jot

25 numeri compresi tra 0 e 9, incremento di default 1 25 numeri compresi tra 0 e 24 25 numeri casuali, partendo da 0 25 numeri casuali, compresi tra 0 e 1000 100 caratteri casuali (a-z)

25 25 -r -r -r

0 9 0 25 0 25 0 1000 -c 100 a z

Il comando rs serve per dare forma ad un array di dati, combinandolo con jot è possibile ottenere dei dati casuali e formattarli in un modo specifico. Per visualizzare 1000 caratteri casuali, organizzati in una matrice 4x4, il comando sarà: jot -r -c 1000 a z | rs 4 4 Il comando rs è seguito dal numero di righe e dal numero di colonne. Per organizzare i dati in 20 colonne ed eliminare gli spazi di divisione del contenuto: jot -r -c 1000 a z | rs -g 0 20 Formare parole casuali e verificarne l’eventuale esistenza nel dizionario: jot -r -c 10000 a z | rs -g 0 4 | xargs -I % grep ^%$ italian Il comando dd80 serve per copiare e convertire un file, nell’esempio prendere il “fileinput.txt” e ne crea una copia, scegliendo le prime 3 lettere dalla prima riga. dd ibs=1 obs=1 count=3 skip=3 if=fileinput.txt of=fileoutput.txt Dato che la prima parola di “fileinput.txt” è “Achille” il file di destinazione “fileoutput.txt” conterrà “ill”.

80

Convert and Copy a File - http://man.cx/dd


40

Comando

Descrizione

df echo 4 | tr \\064 d echo 45678 | tr \\064 - \\067 defgh tr -d \\000 - \\037

Visualizza i filesystem montati Sostituisce con un range ottale Sostituisce con un range ottale Elimina tutti i caratteri da 0 a 37 ottale

Comando

Descrizione

fuser nomefile lsof -p PID lsof

Lista dei PID che hanno aperto il file “nomefile” Quale file ha aperto un processo o una lista di processo Lista i file aperti da tutti i processi

Differenze tra i file Per trovare le differenze tra due file c’è il comando diff diff nomefile1 nomefile2 diff nomefile1 nomefile2 > patch

Restituisce le differenze (20a21,22) Salva in un file le differenze tra due file

È possibile “patchare” un file utilizzando il comando patch, utile per aggiornare un file all’ultima versione. patch nomefile filepatch

Applicherà “filepatch” al file “nomefile”

È possibile confrontare due file utilizzando il comando cmp81, indicato per il confronto di file binari.

Comando

Descrizione

killall nomedelprocesso killall nano killall TextWrangler

Chiude tutte le istanze del processo Chiude tutte le istanze dell’editor nano Chiude tutte le istanze di TextWrangler

Strumenti di rete Comando

Descrizione

open http://www.liis.it curl http://www.liis.it ping 193.204.64.3

Apri la pagina www.liis.it Restituisce il codice HTML della pagina Esegui ciclicamente il ping dell’IP indicato (CTRL+C per bloccare) Verifica l’esistenza di una macchina Visualizza le informazioni sulle interfacce e le connessioni di rete sul PC Statistiche sulle connessioni di rete Filtra ciò che riguarda le connessioni internet Connessioni internet attive Connessioni aperte dall’interfaccia en0 Visualizza informazioni sul proprietario dell’indirizzo IP

ping -q 193.204.64.3 ifconfig netstat netstat -f inet netstat -f inet -p tcp netstat -b -I en0 -f inet -p tcp whois 193.204.64.3

81

Compare Files - http://man.cx/cmp


41

Per visualizzare tutte le interfacce di rete del PC: ifconfig -a Creare uno script che da ifconfig -a tiri fuori tutti gli indirizzi IP utilizzati dalla macchina: #!/bin/bash for i in $(ifconfig -a | grep UP | cut -d: -f1); do ifconfig $i | grep '\binet\b' done | cut -d' ' -f2

Shell Builtin di Bash Comando

Descrizione

source

Equivalente di #include del linguaggio C Include un file all’interno del comando che si sta eseguendo Serve per uscire dal loop (ad esempio while) Dopo l’espansione dei comandi semplici, visualizza l’espansione del prompt quaternario PS4, seguito dal comando ed i suoi argomenti espansi. Fa vedere cosa viene eseguito e mostra l’espansione degli argomenti, se un comando contiene la variabile, fa vedere il valore della variabile (come una modalità di debug) Disattiva la modalità set -x

break set -x

set +x Scrivendo: set -x for i in 1 2 3 4 5 6 > do > echo $i > done

si otterrà l’espansione del commando ed il risultato, ad esempio: + + 1 + 2 + 3 + 4 + 5 + 6

for i in 1 2 3 4 5 6 echo 1 echo 2 echo 3 echo 4 echo 5 echo 6


42

Ricerca avanzata Visualizzare il numero dei file presenti in una cartella: find /path/nomecartella -type f | wc -l Cercare tutti i file con estensione .c in una cartella: find /path/nomecartella -name \*.c | wc -l Per cercare sia i file .h sia quelli .c: find /path/nomecartella -name \*.h -or -name \*.c | wc -l Nel caso di espressioni composte è necessario utilizzare le parentesi: find /path/nomecartella \(-name \*.h -or -name \*.c\) | wc -l


43

Sviluppo del software Un esempio di programma in linguaggio C, il file tombola.c #include <stdio.h> #include <sys/types.h> #include <unistd.h> /*Programma per la estrazione di 90 numeri di tombola.*/ int main(int argc,char **argv) { int n, m, nread, a=1; int tab[91]; char buffer[128]; pid_t pid = getpid();

/* Get our process ID */

srand((unsigned)pid); for (n=1; n<=90; n++ ) { tab[n] = 0; } for ( n=1; n<=10; n++ ) { printf("\n"); fflush(stdout); } m = 0; printf("Premi <Invio> per un'estrazione o Ctrl-C per uscire.\n"); while (a) { n = rand() % 90 + 1; /* 1 to 90 */ /* printf("%d\t%d.\n", n, tab[n]);*/ printf(""); if (tab[n]) { } else { tab[n] = 1; m++; nread = read(0,buffer,128); printf("L'estrazione numero %d e' \t%d.\n", m, n); for ( n=1; n<=10; n++ ) { printf("\n"); fflush(stdout); } }; if (m > 89) {a = 0;} } }


44

Comando

Descrizione

whereis gcc

Visualizza la posizione di GCC, si tratta di un softlink a gcc, il compilatore GNU/Linux per il linguaggio C Apre una guida in formato pseudo-ipertesto, non si tratta di una struttura flat come il man, ma di un modello di ipertesto primordiale. Il tasto Invio consente di aprire un link (contrassegnato da *), q chiude il manuale, b torna all’inizio

info gcc

Il compilatore ha una lunga serie di opzioni. Su MacOS X si può compilare con gcc ad esempio software per un Atari, per altri processori ed altre architetture (Cross Comiling). In alcune pagine di manuale è riportata la dicitura “Fare riferimento alla documentazione mantenuta in formato info”, è il caso di gcc, la cui guida in formato info presenta contenuti più aggiornati. Alcune risorse utili:  Manuale del Preprocessore C - http://gcc.gnu.org/onlinedocs/cpp/  Manuale del Compilatore GCC - http://gcc.gnu.org/onlinedocs/gcc/ Per inviare comandi al preprocessore si utilizza # Per compilare un programma non sono necessarie opzioni aggiuntive, infatti è sufficiente far seguire il nome del file sorgente al comando gcc. Dopo la compilazione viene prodotto un eseguibile denominato a.out Per evitare che l’eseguibile si chiami a.out è possibile utilizzare uno switch del compilatore (con il termine switch si indica un’opzione del compilatore).

Comando

Descrizione

gcc tombola.c gcc tombola.c -o tombola gcc sorgente.c -o destinazione

Compila il programma tombola.c, l’eseguibile sarà a.out Compila il programma tombola.c, l’eseguibile sarà tombola Compila il programma sorgente.c, l’eseguibile sarà destinazione

In Unix i file di intestazione sono contenuti nella cartella di default: /usr/include Per cercare, ad esempio, in quale file d’intestazione si trova la funzione printf è sufficiente eseguire: grep -r printf /usr/include 2>/dev/null | wc Si otterranno moltissimi risultati poiché il comando cercherà tutte le parole che contengono la stringa “printf”, si può raffinare la ricerca: grep -r '\bprintf\b' /usr/include 2>/dev/null | wc Si scoprirà quindi che:  /usr/include contiene i prototipi delle funzioni  /usr/lib contiene le funzioni vere e proprie Si può ancora migliorare la ricerca: grep -r '\bprintf\b' /usr/include 2>/dev/null | grep '\bint\b' |wc


45

E si otterranno 13 risultati. In essi compaiono anche quelli contenenti la stringa “_printf” poiché il carattere underscore è considerato separatore di parola. La ricerca può essere perfezionata ancora: grep -r ' \bprintf\b' /usr/include 2>/dev/null | grep '\bint\b' |wc Si otterrà dunque che la funzione printf è dichiarata nel file stdio.h Analogamente si può cercare quale file di intestazione contiene la dichiarazione della funzione srand: grep -r '\bsrand\b' /usr/include 2>/dev/null | wc Ottenendo che srand è definita nel file stdlib.h Tornando al file tombola.c, si può notare che pur utilizzando la funzione srand, non sono stati inclusi riferimenti al file stdlib.h, ma è molto probabile che qualche libreria allegata includa il file stdlib.h Esiste uno strumento in gcc che consente di vedere tutte le librerie caricate da un file, la catena degli include: gcc -H tombola.c Restituirà tutte le librerie incluse, visualizzate con un annidamento ad albero: . /usr/include/stdio.h .. /usr/include/_types.h ... /usr/include/sys/_types.h .... /usr/include/sys/cdefs.h .... /usr/include/machine/_types.h ..... /usr/include/ppc/_types.h . /usr/include/sys/types.h .. /usr/include/sys/appleapiopts.h .. /usr/include/machine/types.h ... /usr/include/ppc/types.h .... /usr/include/ppc/_types.h .. /usr/include/machine/endian.h ... /usr/include/ppc/endian.h .... /usr/include/sys/_endian.h .. /usr/include/sys/_structs.h . /usr/include/unistd.h .. /usr/include/sys/unistd.h .. /usr/include/sys/select.h ... /usr/include/sys/_structs.h ... /usr/include/sys/_select.h

Si può notare che non è inclusa la libreria stdlib.h, tuttavia è importante ricordare che se una funzione non è stata definite, il C suppone che abbia un’uscita intera e che non abbia variabili. Ovviamente, per non avere risultati inattesi, è importante controllare sempre che una funzione sia definita o che siano corretti i riferimenti di inclusione dei file che contengono la relativa definizione di funzione. È possibile fare in modo che il compilatore aiuti nella scelta delle librerie da includere nel sorgente, per fare ciò è necessario attivare i Warnings nel compilare, cioè la visualizzazione degli avvisi relativi alla compilazione dei file.


46

gcc -Wall tombola.c -o tombola L’opzione -W attiva i warnings, inoltre è necessario specificare il livello di warnings desiderato: all mostrerà tutti i gli avvisi. Compilando il file tombola.c, il compilatore restituirà ora degli avvisi relativi alla “dichiarazione implicita delle funzioni srand e rand”. I programmi così compilati non sono adatti al debugging, il debug si esegue con GDB (GNU Debugging) che consente di scovare facilmente gli errori nei programmi C. Esiste un’opzione per compilare un programma in modo che si possa successivamente eseguire il debug: gcc -g sorgente.c -o destinazione

Make ed il file Makefile I programmi C scritti da un principiante sono generalmente composti da un singolo file, il C però incoraggia a dividere il proprio codice sorgente in più file, è frequente infatti che un progetto di piccole dimensioni sia suddiviso in numerosi file. Non è necessario che, in caso di modifica ad un singolo file, tutti i file debbano essere riprocessati per costruire l’eseguibile. In molti casi infatti è sufficiente compilare un file .o (detto Object File). Esiste inoltre un albero delle dipendenze. Uno strumento, in presenza di modifiche ai prerequisiti (file di partenza), apporta le modifiche esclusivamente alla parte interessata. Questo strumento è MAKE ed è stato creato dalla GNU Foundation. Quando si scarica un software Open Source, in genere si scaricano in sorgenti che devono essere compilati sulla macchina in uso e per fare ciò è necessario conoscere ed utilizzare MAKE. Make utilizza un file denominato Makefile (o MAKEFILE, una lista di dipendenze e di regole per l’esatta risoluzione di queste dipendenze; quando si avvia MAKE, esso verifica nella Current Working Directory l’esistenza del file Makefile. Tale file deve essere strutturato in una certa maniera, seguendo una specifica sintassi. Il secondo rigo del Makefile deve iniziare con un tabulatore, in caso di assenza, non funzionerebbe. Tra la regola (1° riga del file) e la dipendenza (2° riga) non devono esserci righe vuote. Esempio di Makefile: testo : pezzo1.txt pezzo2.txt pezzo3.txt cat pezzo1.txt pezzo2.txt pezzo3.txt > testo.txt pezzo1.txt : sottopezzo1-1.txt sottopezzo2-1.txt cat sottopezzo1-1.txt sottopezzo2-1.txt > pezzo1.txt pezzo2.txt : sottopezzo1-2.txt sottopezzo2-2.txt cat sottopezzo1-2.txt sottopezzo2-2.txt > pezzo2.txt pezzo3.txt : sottopezzo1-3.txt sottopezzo2-3.txt cat sottopezzo1-3.txt sottopezzo2-3.txt > pezzo3.txt


47

Scrivendo a terminale: make testo Il compilatore seguirà le dipendenze e compilerà il file. Make verifica la data dei file (dei vari sottopezzi) e se trova una data successiva a quella del file compilato, compila la parte necessaria. Il programma make vale in generale, ad esempio potrebbe essere utilizzato da una redazione che ha un programma per assemblare gli articoli dei vari giornalisti e restituisce il giornale impaginato. Inoltre se si scrive make tombola , make trova il file tombola.c (se presente nella CWD) e presume si voglia compilare il file. Nel caso in cui il file eseguibile sia presente ed aggiornato, il programma restituirà: make: 'tombola' is up to date. Modificando il file tombola.c e rilanciando il comando make tombola Make intuisce euristicamente che si debba compilare il file C, lanciando automaticamente il comando: cc tombola.c -o tombola Make riconosce una serie di linguaggi di programmazione di default. Per approfondimento si rimanda al libro “Advanced Programming in the Unix Environment”82 In un makefile: DIRS = definizione... $(DIRS) $$i

Definizione di macro, tutto ciò che è a destra dell’uguale Utilizzo delle variabili proprie di make Utilizzo delle variabili dello shell

È possibile che in un makefile ci siano i target ma non i prerequisiti. Un esempio: all: $(MAKE) ‘./systype.sh’ macos: for i in $(DIRS); do \ (cd $$i && $(MAKE) -f macos.mk ) || exit 1; \ done Con il comando seguente, si indica al make di utilizzare un makefile alternativo make -f

82

Advanced Programming in the Unix Environment - http://www.apuebook.com


48

Un esempio di makefile alternativo: include ../Makefile.defines.macos PROGS = access cdpwd all:

${PROGS}

savedid: savedid.o $(LINK.c) -o savedid.o $(LDLIBS) Segue ora un esempio di definizioni comuni del make adattate per un sistema Mac OS X. WKDIR=/Users/nomeutente/Documents/PSR2012/apue.2e CC=gcc COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDDIR) $(LDFLAGS) LDDIR=-L../lib LDLIBS=../lib/libapue.a CFLAGS=-ansi -I$(WKDIR)/include -Wall -DMACOS $(EXTRA) #Our library that almos every program needs LIB=../libapue.a # Common temp files to delete from each directory TEMPFILES=core core.* *.o temp.* *.out typescript* La compilazione produce dei file .o, cioè file oggetto. GCC per impostazione predefinita esegue anche il linking del programma, utilizzando invece l’opzione -c , gcc si limiterà alla sola compilazione dei file oggetto, non eseguendo il linking. Con la macro seguente infatti, si impedirà a gcc l’esecuzione del linking: COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c Nel caso presentato, il linking viene ridefinito con una riga specifica, nella quale si indica al linker dove trovare le librerie personalizzate. LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDDIR) $(LDFLAGS) L’utente non può inserire le proprie librerie nella directory /usr/lib ; in questa cartella (default per le librerie) solo l’amministratore del sistema può aggiungere nuove librerie. Nell’esempio presentato sono stati definiti tutti i flags da utilizzare nella compilazione, in particolare con la riga: CFLAGS=-ansi -I$(WKDIR)/include -Wall -DMACOS $(EXTRA) Dove con -ansi si impone al compilatore l’utilizzo dello Standard C, infatti non saranno accettati sorgenti che non saranno conformi con lo standard ANSI C.


49

Le direttive del preprocessore possono essere passate da riga di comando con l’opzione -D, nell’esempio infatti si nota: -DMACOS $(EXTRA) Make si blocca al primo errore incontrato e non esegue il resto delle operazioni, per continuare l’esecuzione anche in caso di errori è necessario utilizzare l’opzione -i make -i

Debug Per eseguire il debug di un file è necessario compilarlo utilizzando una specifica modalità: cc -ggdb tombola.c -o tombola Per aprire il file in modalità debugging, eseguire: gdb ./tombola All’interno del debugger è possibile utilizzare una lista di comandi:

Comando

Descrizione

l

Comando LIST, visualizza il sorgente C del programma (prime 10 righe). La ripetizione del comando consente di avanzare tra le righe del programma. Inserisce un breakpoint (punto d’interruzione nel programma) alla riga 20, vuol dire che il debugger eseguirà il programma fino alla riga 24 esclusa. È possibile verificare il nome di una variabile scrivendo il comando p seguito dal nome di una variabile Visualizza l’indirizzo di memoria della variabile “nomevariabile” Comando STEP, esegue l’istruzione successiva e mostra al terminale la prossima Elimina il breakpoint creato alla riga 20

b 20

p nomevariabile p &nomevariabile s clear 20

Comandi vari Comando

Descrizione

ssh hplinux2.unisalento.it ls ssh hplinux2.unisalento.it 'ps -e' ssh hplinux2.unisalento.it 'uptime' stty -echo stty echo stty -a

Esegue il comando ls sulla macchina remota Esegue il comando ps -e sulla macchina remota Carico medio del sistema sulla macchina remota Scrivi senza che il testo inserito sia visibile Ripristina l’echo Visualizza tutte le associazioni


50

Comando

Descrizione

whereis sh ls -la /bin/sh

Restituisce il percorso di sh: /bin/sh Restituisce le informazioni su /bin/sh

ls -lai /bin/sh

Visualizza anche l’inode

ls -lai /bin/bash

Informazioni su /bin/bash

-r-xr-xr-x 1 root wheel 1244960 Jun 18 2009 /bin/sh 1003466 -r-xr-xr-x 1 root wheel 1244960 Jun 18 2009 /bin/sh 1003420 -rwxr-xr-x 1 root wheel 1244928 Jun 17 2009 /bin/bash

Per visualizzare il numero di tutti gli script contenuti nella cartella /etc Per visualizzare gli script shell (prima versione) grep -r '#!/bin/sh' /etc 2>/dev/null | wc Per visualizzare gli script bash grep -r '#!/bin/bash' /etc 2>/dev/null | wc Cerca tutti gli script SH e restituisce il nome grep -r '#!/bin/sh' /etc 2>/dev/null Esistono degli script periodici, situati nelle relative cartelle: daily, monthly, weekly. L’esecuzione di tali script è regolata dal file periodic.conf Per visualizzare tale file con TextWrangler: edit /etc/defaults/periodic.conf Il programma che esegue le azioni programmate è periodic

Comando

Descrizione

whereis periodic

Restituirà /usr/sbin/periodic Visualizzare il contenuto dello script

edit /usr/sbin/periodic

È possibile creare un file temporaneo scrivendo la riga: mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX Il comando eval83 rivaluta l’espressione che lo segue; esegue un ulteriore giro di valutazione. Quando si esegue il comando ps -ef per visualizzare la lista dei processi attivi, nell’output del comando compaiono le colonne VSZ e RSZ che indicano:

83

Comando Eval - http://man.cx/eval


51

 

Virtual Size Set (VSZ) - Memoria virtuale occupata da un processo Real Size Set (RSZ) - Memoria reale occupata

Si deve tenere presente che, ad esempio, le librerie C sono allocate una sola volta per tutti i processi che ne fanno richiesta, pertanto non sarà possibile effettuare un conteggio accurato di quanta memoria occupa ciascun processo. Con il comando top è possibile avere una visualizzazione dinamica dei processi con informazioni dettagliate su ciascun processo attivo. È possibile avere una visualizzazione statica di top, eseguendo il comando: top -l1 Su MacOS X esiste il comando vmmap che produce una mappa della memoria virtuale. Su GNU/Linux invece, esiste una mappa della memoria per ogni processo, infatti in /proc esiste un file maps per ciascun processo attivo. Il comando curl consente di visualizzare siti web all’interno del terminale, di estrarre dati da essi oppure ancora, di visualizzare gli headers di una pagina web.

Comando

Descrizione

curl http://www.google.it curl -I http://www.google.it

Restituisce il codice HTML della pagina web indicata Restituisce gli Headers della pagina web indicata

È possibile reindirizzare l’output del comando curl, ad esempio per scrivere gli headers di una pagina web all’interno di un file, così facendo, curl visualizzerà a terminale esclusivamente una statistica dei dati scaricati (che viene inviata allo stderr) mentre scriverà nel file di testo indicato gli headers, come nel comando seguente. curl -I http://www.google.it 1>nomefile.txt

Conversione di date In alcune circostanze è utile convertire una data dal formato standard al formato in secondi a partire da epoch (01/01/1970) così da poter eseguire semplicemente confronti oppure ordinamenti. Si tenga presente che il formato di visualizzazione della data è condizionato dalle impostazioni sulla localizzazione. In Mac OS X per passare dall’output del comando date ad epoch, con localizzazione en-US date -j -f "%a %b %d %T %Z %Y" "$(date)" +%s In Mac OS X per passare dall’output del comando date ad epoch, con localizzazione it-IT date -j -f "%a %b %d %Y %T %Z" "$(date)" +%s Per verificare la localizzazione del terminale della macchina in uso, utilizzare il comando locale


52

Su un terminale Linux per passare dall’output del comando date ad epoch, con localizzazione en-US date -d "$(date)" +%s L’output del comando: ps -cax -opid,lstart che visualizza l’istante di inizio di un processo, fornisce la data nel formato84: "%a %m %b %T %Y Per cui il comando di conversione in Mac OS X è: date -j -f "%a %m %b %T %Y" "Dom

3 Apr 10:25:14 2011" +%s

Su un’altra macchina con localizzazione differente è: date -j -f "%a %d %b %Y %T %Z" "$(date)" "+%s" poiché il comando date restituiva: Mar 19 Giu 2012 15:34:06 CEST Per far funzionare il comando con i risultati restituiti dal comando curl quando sono in inglese, è possibile cambiare la localizzazione del tempo solo per l’esecuzione del comando: LC_TIME="en_US.UTF-8" date -j -f "%a, %d %b %Y %T %Z" "Thu, 05 Jan 2012 18:12:40 GMT" "+%s"

Che risolve la seguente linea di header: Last-Modified: Thu, 05 Jan 2012 18:12:40 GMT in: 1325787160 Per modifica la localizzazione delle date:

Comando

Descrizione

LC_TIME="en_US.UTF-8" LC_TIME="it_IT.UTF-8"

Imposta la visualizzazione delle date in formato inglese USA Imposta la visualizzazione delle date in formato italiano

84

Fare riferimento al manuale del comando date - http://man.cx/date


53

Per visualizzare la priorità dei processi attivi: ps -e -o pid,nice,comm Per conoscerla priorità del processo mdworker ps -e -o pid,nice,comm | grep md Tale processo, che si occupa dell’indicizzazione dei file presenti sul pc, ha una priorità (numero di nice) pari a 17 su un massimo di 20, quindi priorità molto bassa. Il numero di nice è compreso tra -20 (priorità altissima) e 20 (priorità bassissima). È possibile visualizzare la priorità dei processi anche utilizzando il comando seguente: ps axl


54

Simulazioni d’esame Esercizio Scrivere in bash un loop che incrementi una variabile e stampare il valore di tale variabile dopo un secondo. contagiri.sh #!/bin/bash i=0 trap 'echo $i; i=0' SIGUSR1 ./trigger.sh $$ & # lancia lo script, prende come argomento il PID del bash e lo pone in background while true do ((i++)) done trigger.sh #!/bin/bash while true do sleep 1 kill -SIGUSR1 $1 done

Esercizio Scrivere uno script bash in grado di fornire una rappresentazione grafica della bitmap degli inode nel file system in cui si trova la propria home directory indicando con una 'x' gli inode occupati e con un '.' quelli liberi. Innanzitutto è bene conoscere qualche comando:

Comando

Descrizione

df -k df -i

Visualizza i volumi montati Volumi occupati, saranno visualizzati anche gli inode

Ăˆ possibile visualizzare ad esempio un range di inode: find / -inum +6070014 -inum -8538208 -exec stat -f%i {} \; 2>/dev/null find / -inum 6070014 -exect stat -f%i {} \; 2>/dev/null


55

E su Linux: find / -inum +6359000 -inum -6360000 -exec stat -c%i {} \; 2>/dev/null Si giungerà cosÏ allo script che risolve l’esercizio: inodebitmap.sh #!/bin/bash if [ $# -ne 2]; then echo 'Usage inodebitmap.sh inode_start how_many'; exit; fi inode_start=$1 inode_end=$(($1 + $2)) a=($(find / -inum +$inode_start -inum -$inode_end -exec stat -c%i {} \; 2>/dev/null)) for ((i=inode_start; i<=inode_end; i++)); do b[i]=.; done for i in ${a[*]}; do b[i]=x; done for ((i=inode_start; i<=inode_end; i++)); do echo ${b[i]}; done | rs -g 0 50 Un esempio di utilizzo: ./inodebitmap.sh 6359581 1000


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.