uni
Comandi Unix Network
Unix nasce nel 1969.
Ne escono 3 derivati:
- BSD (1977)
- Darwin (MacOS)
- GNU (1984)
- GNU/Linux
- Solaris (1992)
Caratteristiche di Unix
Unix è Case sensitive!
- multitasking
- multiutente
- portabile
- modulare
Redirezione IO
I processi hanno tre canali di input/output standard:
-
stdin: input da tastiera
-
stdout: output da schermo
-
stderr: messaggi di errore su schermo
Possiamo reindirizzare l’output dei comandi dentro file o altro: -
>invia stdout ad un file, se il file non esiste viene creato, se esiste viene sovrascritto -
2>invia stderr in un file -
&>invia sia stdout sia stderr in un file -
>>, 2>>, &>>stessa cosa ma non sovrascrive, concatena -
comando > fileSTDOUT 2> fileSTDERRscrive stdout in un file e stderr in un altro -
<recupera l’input da un file
Pipeline
Il simbolo | collega l’output di un comando all’input del successivo
Comandi Unix di base
shutdowndi default solo root può lanciarlo-h nowhalt-r nowreboot
cdchange directoryecho "contenuto" > file.txtsostituisce il contenuto con quello nuovo.
Per aggiungere invece bisogna usareecho "contenuto" >> file.txtpwdprint working directory, mostra il percorso assoluto attualelselenca elementi cartella attuale-llong (più informazioni per ogni file)-aall (anche file nascosti)
manmostra il manuale contenente la descrizione esaustiva del comando specificato, la sintassi, le opzioni, i messaggi di erroreman manè il manuale di man, che è diviso in sezioniman comandoè il manuale del comandoman 3 comandova alla al manuale della funzione c di comando- non solo per comandi: anche funzioni del kernel, funzioni delle librerie Header file, file di configurazione..
whatisinformazioni di base su argomentoaproposserve per ricercare una parola in nomi e descrizioni, che comandi ho per fare una determinata cosamkdir nomefa cartellarmdir cartellarimuove cartella, ma solo se è vuotacp src destcp src1 src2 dst_dircopia tutti i file dentro un cartella
mv src desttouch nome_fileaggiorna il timestamp di accesso e modifica di un file, se il file non esiste lo creacat file1 file2concatena il contenuto dei file e li stampa a video nello standard output, se è un solo file ne stampa solo il contenutorm file1 file2rimuove filerm -r nome_cartellacancella la cartella e tutto il suo contenutorm -drimuove cartelle vuoterm -fforce: non prompta, ignora file non esistenti
lessvisualizza file interattivamente un po’ alla voltahead/tailpermetto di visualizzare solo la prima/ultima parte di uno o più file-cspecifica numero di byte-nspecifica numero di righe (di default 10)
sortsuswitch user serve per accedere al terminale di un altro utente, se non specifico argomento, si accede al terminale di root, chiede la password dell’utente con il quale si vuole accederesudo comandoserve per lanciare un comando come un altro utente, se non specifico che utente, si intende root, l’utente attuale deve far parte del gruppo sudoers, viene chiesta la password dell’utente correntechmod modalità targetmodalità: 777=111111111 → rwxrwxrwx, 600=110000000 → rw-------
Utenti e Gruppi
Ogni utente nei sistemi Unix è identificato da un username ed un UID numerico (user ID, partono da 1000).
Ogni utente deve appartenere ad almeno un gruppo (normalmente il primary group).
Ogni gruppo è identificato da un group name ed un GID numerico (group ID).
Comandi vari
passwd
# permette di cambiare la password (sfrutta il permesso SUID)
id [username]
# visualizza UID, gruppo principale e altri gruppi dell'utente corrente o di quello selezionato
groups [username]
# visualizza i nomi dei gruppi dell'utente corrente o di quello selezionato
su [username]
# switch user, permette di accedere al terminale di un altro utente, o di root
sudo -u username comando
# permette di eseguire un comando con i privilegi di un altro utente
# viene chiesta la password dell'utente correte
# l'utente attuale deve far parte del gruppo sudoGestione utenti
Per aggiungere o rimuovere utenti è necessario avere i privilegi di root.
adduser username
deluser usernamePermessi di accesso al filesystem
Per ogni file (directory) sono definiti:
- utente proprietario: owner
- gruppo proprietario: group owner
Quindi per ogni file ci sono tre classi di utenti:
- owner
- utente appartenente al group owner
- others
A ciascuna classe di utenti vengono applicati permessi specifici; i permessi per file sono:
- r - read
- w - write
- x - execute (binario o script)
il permesso di scrittura non permette di cancellare un file: per la cancellazione di un file valgono i permessi della directory
I permessi per directory sono:
- r - permette di leggere il contenuto
- w - permette di modificare il contenuto
- x - permette di attraversare una cartella (senza permesso non possiamo fare
cdsu quella cartella)
Rappresentazione simbolica dei permessi
I permessi possono essere visualizzati con
ls -loutput:
-rw-r--r-- 1 studenti studenti 10 ott 9 13:17 esempio.txt
drwxr-xr-x 2 studenti studenti 4096 ott 9 13:19 subDir
#--- permessi owner
# --- permessi group owner
# --- permessi others
# - vuol dire file
# d vuol dire directory
# i permessi sono in ordine: owner - group owner - othersRappresentazione ottale
Per ogni classe di utenti specifica i permessi tramite una cifra in base 8. Alla cifra si somma:
- 4 se è permessa la lettura
- 2 se è permessa la scrittura
- 1 se è permessa l’ esecuzione
e.g. 7→111 = rwx
e.g. 5→101 = r-x - 777 = sono garantiti tutti i permessi a tutti gli utenti
- 750 = owner ha tutti i permessi, group owner non può modificare, others non hanno nessun permesso.
Cambiare i permessi
# rappresentazione ottale
chmod XXX filename
# rappresentazione simbolica
chmod [who] [how] [which] filename
# [who]={u,g,o} # owner,group owner, others
# [how]={+,-,=}
chmod -R # applica il cambiamento in modo recursivo a tutti i file e cartelle contenuti nella directoryPuò essere eseguito solo dal proprietario del file (o con -R proprietario di tutti i file nella cartella).
Permessi aggiuntivi
- SUID - durante l’esecuzione il processo acquisisce i privilegi del proprietario del file, non di chi lo esegue.
- SGID - durante l’esecuzione il processo acquisisce i privilegi del gruppo proprietario del file, non di chi lo esegue.
esempio: il comandopasswdha il permesso SUID.
Per impostate SUID si mettesal posto dellaxnei permessi owner.
Per impostare SGID si mettesal posto dellaxnei permessi group owner.
Per la rappresentazione ottale si utilizza un’ulteriore cifra
prima delle 3 cifre relative alle classi di utenti. Questa cifra
ottale è ottenuta come somma di
- 4 se è attivo il permesso SUID
- 2 se è attivo il permesso SGID
Privilegi di un processo
I privilegi di un processo dipendono da:
- effective user ID (EUID)
- effective group ID (EGID)
Normalmente quando un processo viene eseguito, i suoi EUID ed EGID corrispondono direttamente all’UID e al gruppo principale dell’utente che ha eseguito il processo stesso.
Per permettere ad un comando/script di essere eseguito con
privilegi diversi rispetto a chi lo esegue, è possibile impostare
nel file i permessi SUID e SGID.
Comandi chown e chgrp
[root] chown username file
# permette di impostare username come nuovo proprietario di fileFile di Configurazione
/etc/passwd
Questo è un file con informazioni pubbliche sugli utenti
- si può aprire in editing con vipw
username:x:UID:GID:,,,:cartellaHome:/bin/bashxindica che la password è cifrata e si trova in/etc/shadowcartellaHomeindica il percorso assoluto della cartella personale home, server per impostare la variabile d’ambiente $HOME- la shell può impostata a
/sbin/nologino/bin/falseper indicare che non è possibile fare il login con tale utente
/etc/shadow
Questo è un file contenente informazioni sensibili.
- si può aprire in editing con
vipw -s
utente:$hashing algorithm$salt$hash(salt+password):ultimaModifica:etàMin:etàMax:avviso:::- ultimaModifica della passowrd, contando i giorni dal 1970
- età min e max: durata minima e massima della password
- salt: caratteri casuali
- periodo di avviso: quanti giorni prima della scadenza della password viene notificato l’utente
- periodo di inattività: giorni dopo la scadenza della passwordd in cui questa è ancora accettata
- scadenza: data scadenza dell’account
- campo riservato: riservato per utilizzo futuro
su linux sha512sum
su macOS shasum -a 512
quando l’utente inserisce la password, il sistema vi aggiunge il salt, e calcola l’Hash, che confronta con l’Hash salvato in
/etc/shadow.
Gestione dei Gruppi
Per aggiungere o rimuovere gruppi servono i privilegi root.
- addgroup
- delgroup
- newgrp
- gpasswd
- solo root può aggiungere/rimuovere gli amministratori
- se la passoword non è impostata, solo i membri del gruppo possono averne i privilegi
- se la password è impostata, gli utenti del gruppo non ne necessitano, invece gli altri utenti possono acquisire temporaneamente i privilegi del gruppo tramite il comando
newgrp - le password di gruppo sono intrinsecamente poco sicure, in quanto conosciute da più utenti. Quindi se succede qualcosa usando quella password, non è possibile imputarlo ad una persona.
# aggiungere un utente ad un gruppo
gpasswd -a utente gruppo
# rimuovere un utente da un gruppo
gpasswd -d utente gruppo
# definire i membri di un gruppo
gpasswd -M utente1, utente2, ... gruppo
# definire gli amministratori di un gruppo
gpasswd -A utente1, utente2, ... gruppo
# impostare/cambiare la password di un gruppo
gpasswd gruppo
# rimuovere la password di un gruppo
gpasswd -r gruppo
newgrp gruppo
# con questo comando, il gruppo specificato diventa il nuovo gruppo primario dell'utente per la sessione di login correnteFile di configurazione dei gruppi
/etc/group
File contentente informazioni pubbliche sui gruppi.
Si può aprire con il comando vigr.
groupname:x:GID:lista,utentix: vuol dire password esistente e salvata in gshadow- altri simboli (
*o!) (o campo vuoto) vogliono dire password non esistente - lista utenti: separati da virgola, non contiene l’utente per il quale il gruppo è il primary group, poiché questa informazione è già in `/etc/passw
/etc/gshadow
File con informazioni sensibili (password e amministratori).
nomeGruppo:passwordcifrata:GID:amministratori:membriGli amministratori possono cambiare la password e aggiungere/rimuovere utenti al/dal gruppo.
Processi in Unix
Unix è una famiglia di sistemi operativi multiprogrammati.
Il processo Unix mantiene spazi di indirizzamento separati per dati e codice.
Lo spazio di indirizzamento dei dati è privato, la comunicazione fra processi avviene tramite scambio di messaggi.
Lo spazio di indirizzamento del codice è invece condivisibile, più processi possono eseguire lo stesso codice.
Unix adottauna politica di assegnamento della CPU ai processi basata sulla divisione di tempo (time sharing - round robin - Algoritmi di Scheduling).
Stati di un processo
Un processo può essere in diversi stati:
- init
- pronto
- running
- zombie
- terminato
- sleep/bloccato
- swapped
Immagine di un processo Unix
Il descrittore di un processo (PCB: process control block) è suddiviso in due strutture dati distinte:
- process structure: informazioni indispensabili e quindi sempre in memoria
- PID
- Stato
- Riferimento ad aree dati e stack
- Riferimento (indiretto) al codice
• PID padre
• Priorità
• Riferimento al prossimo
processo
• Puntatore alla User
Structure
• …
- user structure: informazioni utili solo quando il processo è in memoria
- Copia registri CPU
• Info su risorse allocate
• Info su gestione eventi
asincroni (segnali)
• Directory corrente
• Utente proprietario
• Gruppo proprietario
• Argc, argv, path, …
• …
- Copia registri CPU
System Call per i processi
- fork: creazione di processi
- exit: terminazione
- wait: sospensione in attesa della terminazione dei figli
- exec: sostituzione di codice e dati
PID e PPID
pid_t getpid() // restituisce il PID del processo
pid_t getppid() // restituisce il PID del processo padrefork
Ogni processo è in grado di creare dinamicamente processi.
Il processo creato (figlio) ha uno spazio dati separato, ma condivide con il processo padre il codice.
pid_t fork(void)
/*
non richiede parametri
restituisce:
- al padre: il PID del figlio, valore negativo se fallisce
- al figlio: zeroIl figlio condivide il codice del padre ed eredita dal padre una copia delle aree dati globali, stack, heap e user structure, ottiene anche lo stesso valore di PC (program counter - rip) e di tutti gli altri registri.
Quindi dopo la fork, padre e figlio partono dalla stessa istruzione (la fork). Il loro comportamento viene differenziato sfruttando il valore di ritorno della fork.
Terminazione dei processi
Esistono due tipi di terminazione:
- volontaria:
exit() - involontaria:
- azioni illegali
- interruzioni causate dala ricezione di segnali
exit
void exit(int status)
/*
chiamata senza ritorno (ovviamente)
permette di comunicare al padre lo stato di terminazione
*/wait
pid_t wait(int *status)
/*
il padre può ottenere lo stato di terminazione del figlio mediante la syscall wait
wait ritorna il PID del figlio che è terminato
status è l'indirizzo della variabile dove verrà salvato lo stato di terminazione del figlio
wait sospende il padre se tutti i figli sono ancora in esecuzione
ritorno immediato con informazioni di terminazione se almeno un figlio è terminato (zombie)
ritorno con valore negativo se non ci sono figli
*/variabile status
Contiene informazioni su come il figlio è terminato.
Se il byte meno significativo di *status è zero, allora la terminazione è stata volontaria, in questo caso il byte più significato contiene lo stato di terminazione.
Macro per gestire status
Sono definite in <sys/wait.h>
WIFEXITED(status): ritorna vero se terminata volontariamenteWEXITSTATUS(status): ritorna lo stato di terminazione
Sostituzione di codice
Un processo può sostituire il programma (codice e dati) che sta eseguendo utilizzando una syscall della famiglia exec():
execl(char *path, char *arg0, ... , char *argN, NULL)
/* lista di parametri di lunghezza variabile, terminata dal puntatore nullo
path: percorso assoluto del comando, ad esempio "/bin/ls"
arg0: nome del programma da eseguire
arg1-N: argomenti del comando
*/
execle()
execclp()
execv()
execve()
execvp()Queste syscall sono senza ritorno se hanno successo
Gerarchia dei Processi
I sistemi Unix prevedono un init system, un processo mandato in esecuzione dal kernel durante il boot.
Questo è il primo processo ad andare in esecuzione, infatti ha PID = 1.
Tutti gli altri processi discendono da init.
In Debian/Ubuntu viene utilizzato systemd come gestore dei processi.
Possiamo visualizzare l’albero dei processi con pstree.
Identificatori di un processo
- PID: ID univoco del processo
- PPID: ID del processo padre
- PGID: ID del process group a cui il processo appartiene
- RUID, RGID: Real User/Group ID
- EUID, EGID: effective User/Group ID: possono
Gli identificatori che determinano i permessi del processo si dividono in real e effective:
- RUID : real user ID: ID dell’utente che ha mandato in esecuzione il processo
- RGID: real group ID: ID del gruppo primario dell’utente che ha mandato in esecuzione il processo
- EUID: effective user ID
- EGID: effective group ID
EUID e EGID possono differire da RUID e RGID se il comando eseguito ha il bit SUID o SGID attivo.
Vengono utilizzati per definire i privilegi di accesso alle risorse e di invocazione di system call del processo.
Un processo utente può inviare segnali ad un altro processo solo se il suo EUID o RUID coincide con il RUID del processo destinatario.
Funzioni get per identificatori
• pid_t getpid()
• pid_t getppid()
• pid_t getpgrp()
• uid_t getuid()
• uid_t getgid()
• uid_t geteuid()
• uid_t getegid()Gruppi di Processi
I processi sono organizzati in gruppi: quando un nuovo processo viene mandato in esecuzione da terminale, al processo viene associato un nuovo process group, se questo genera figli, questi appartengono allo stesso gruppo del padre.
Nota che il gruppo viene preservato anche dalla syscall exec.
I gruppi permettono di mandare segnali ad una gerarchia di processi e sono alla base del job-control offerto dalla shell.
Priorità dei processi - nice
Lo scheduler Unix assegna la CPU ai processi tenendo conto di un livello di priorità assegnato a ciascun processo, questa priorità dipende principalmente dalla classe di scheduling del processo: real time (interattivi) vs batch (normale).
La priorità dei processi normali può essere in parte controllata mediante il concetto di niceness e la relativa syscall nice.
Ad ogni processo è associato un valore di niceness nell’intervallo [-20.19].
Un valore di niceness alto porta a bassa priorità di esecuzione.
Solo root può ridurre la niceness di un processo, un utente può solo aumentare la niceness dei suoi processi.
Comandi nice e renice
nice -n valore_nice comandoIl comando nice permette di mandare in esecuzione un processo con un valore di niceness specificato.
renice valore_nice PIDIl comando renice permette di modificare la niceness di un processo già in esecuzione.
Sincronizzazione basata sui segnali
I processi Unix aderiscono al modello ad ambiente locale: hanno uno spazio di indirizzamento privato e non hanno condivisione di variabili.
I processi possono solo sincronizzarsi (imposizione di vincoli temporali) e scambiare messaggi, mediante system calls.
I segnali
I segnali sono interrupt software: permettono la notifica di eventi asincroni da parte di un processo a uno o più processi.
La ricezione di un segnale ha tre possibili effetti sul processo:
- viene eseguita una funzione di gestione (handler) definita dal programmatore
- viene eseguita un’azione predefinita dal sistema operativo (default handler)
- il segnale viene ignorato
Nei primi due casi il processo si comporta in modo asincrono rispetto al segnale: l’esecuzione viene interrotta per eseguire l’handler, dopo la gestione, se il processo non è terminato, riprende dall’istruzione successiva all’ultima eseguita prima dell’istruzione.
La lista dei segnali è definita nel file di sistema signal.h, ciascun segnale è identificato da un intero e da un nome simbolico.
Per aprire la pagina del manuale sui segnali: man 7 signal.
Alcuni segnali
| Nome segnale | # segnale | Descrizione segnale | default handler |
|---|---|---|---|
| SIGHUP | 1 | Hang up (il terminale è stato chiuso) | termina il processo |
| SIGINT | 2 | Interruzione del processo. CTRL+C da terminale. | termina il processo |
| SIGQUIT | 3 | Interruzione del processo e core dump. CTRL+\ da terminale. | |
| SIGKILL | 9 | Interruzione immediata. Questo segnale non può essere ignorato ed il processo che lo riceve non può eseguire operazioni di chiusura. | |
| SIGTERM | 15 | Terminazione del programma. | |
| SIGUSR1 | 10 | Definito dall’utente | termina il processo |
| SIGUSR2 | 12 | Definito dall’utente | termina il processo |
| SIGSEGV | 11 | Errore di segmentazione. | |
| SIGALARM | 14 | Il timer è scaduto | ignora |
| SIGCHILD | 17 | Processo figlio terminato | ignora |
| SIGSTOP | 19 | Ferma temporaneamente l’esecuzione del processo: non può essere ignorato | |
| SIGSTP | 20 | sospende l’esecuzione del processo. CTRL+Z da terminale | |
| SIGCONT | 18 | Il processo può continuare, se era stato fermato da SIGSTOP o SIGSTP |
System Call per i segnali
signal
Permette di definire la funzione che dovrà gestire il segnale con identificativo sig.
typedef void (*sighandler_t)(int);
sighandler_t signal(int sig, sighandler_t handler)Handler può valere anche SIG_IGN (ignora il segnale) o SIG_DFL (ripristina azione di default).
Restituisce un puntatore al precedente handler del segnale, SIG_ERR in caso di errore.
Pagina del manuale: man 2 signal.
Figlio
Il figlio eredita dal padre le informazioni relative alla gestione.
Eventuali signal eseguite dal figlio non hanno effetto sul padre
exec
Le syscall exec non mantengono le associazioni segnale-handler, fatta eccezione per i segnali ignorati, continueranno ad essere ignorati.
kill
int kill(pid_t pid, int sig)Invia il segnale sig al processo pid.
- pid > 0 → segnale viene inviato a pid
- pid == 0 → segnale inviato a tutti i processi nello stesso process group del chiamante (tutti i figli del chiamante)
- pid == -1 → segnale inviato a tutti i processi a cui il chiamante può inviare segnali
- pid < -1 → il segnale viene inviato ai processi il cui
process groupè-pid
pause
int pause(void)Il processo si sospende, va in stato sleeping fino alla ricezione di un (qualsiasi) segnale.
Ritorna -1 se il gestore non termina l’esecuzione del processo.
sleep
unsigned int sleep(unsigned int seconds)Il processo chiamante va in stato sleep fino a che:
- sono passati
secondssecondi - arriva un segnale che non viene ignorato
Ritorna zero se è passato il tempo previsto, altrimenti il tempo rimasto dopo l’arrivo di un segnale.
alarm
usigned int alarm(unsigned int seconds)Provoca la ricezione di un segnale SIGALRM dopo seconds.
- di default il processo viene terminato
- si può avere un solo alarm, quindi se lancio due
alarm, l’ultimo sovrascrive il primo - se seconds è zero viene eliminato un eventuale allarme invocato precedentemente
Ritorna zero se non c’era un allarme programmato, altrimenti ritorna il numero di secondi mancanti all’ultimo allarme programmato.
Invio di segnali da terminale
kill [options] pid [pid2..]Il comando kill permette l’invio di segnali a processi da terminale. Il segnale inviato di default è SIGTERM.
kill -l mostra l’elenco dei segnali disponibili.
kill -SEGNALE pid
# invia il segnale SEGNALE al processo pidUn utente normale può inviare segnali solo ai processi di cui è proprietario.
Visualizzazione processi - process status
ps [opzioni]Il comando ps permette di visualizzare uno snapshot attuale dei processi in esecuzione.
-u utente # visualizza i processi dell'utente specficato
u # formato output utile all'analisi dell'utilizzo delle risorse
a # processi di tutti gli utenti
x # anche processi che non sono stati generati da terminali
o # mostra solo i campi specificati di seguito
-O # mostra i campi specificati di seguito, oltre a quelli di defaultStati principali
S # sleep
T # bloccato
R # running
Z # zombie
man ps # per vedere tutti i possibili statiJob control
Un job in esecuzione in foreground ha il controllo di standard input, output e standard error: il processo “prende il controllo del terminale” e lo restituisce alla shell alla sua terminazione.
È possibile eseguire job in background:
comando &Operazioni sui processi fermati
Un processo in foreground può essere fermato inviando il segnale SIGTSTP (ovvero ctrl+z).
È possibile intervenire sui job che sono stati fermati in questo modo:
- si utilizza
jobsper ottenere l’identificatore del job (JOB_ID) fg JOB_IDfa ripartire il job in foregroundfg JOB_IDfa ripartire il job in background
kill
È possibile usare il comando kill anche con i job:
kill %JOB_ID # invia SIGTERM al job specificato
kill -n SIG %JOB_ID # invia SIGdisown e nohup
Se il terminale viene chiuso i job in esecuzione ricevono il segnale SIGHUP, che di default termina il processo.
nohup comandoIl job eseguito in questo modo è immune a SIGHUP.
Il job non ha più accesso allo stdin: in caso di lettura ottiene EOF, lo stdout viene rediretto su un file chiamato nohup.out.
disown %JOB_IDRende immune a SIGHUP un job già in esecuzione.
Il job viene rimosso dalla tabella dei job, quindi la shell non invierà più il segnale SIGHUP quando viene chiusa.
È opportuno fare in modo che il job non legga più dallo stdin e che un eventuale output venga rediretto su un file per evitare errori durante l’esecuzione.
Monitorare il sistema - top
Permette di visualizzare i processi e di effettuare operazioni su di essi in modo interattivo:
- i processi sono ordinati in ordine di utilizzo decrescente della CPU
- è possibile inviare segnali ai processi e cambiarne il valore di niceness
- vengono visualizzate anche informazioni complessive sul sistema (carico CPU, utilizzo della memoria)
comandi interattivi
- h: help
- d: intervallo di aggiornamento (delay)
- k: invio di segnale
- n: numero di processi da visualizzare
- r: renice
- u: utente da visualizzare
- q: quit
Gestione File
find
Questo comando è uno strumento molto potente per trovare file, permette di effettuare la ricerca combinando dei testi sulle proprietà dei file:
- filename
- filetype
- owner
- permessi
- timestamp
La ricerca non è influenzata dal contenuto del file.
Rende inoltre possibile eseguire comandi (actions) sui file trovati.
find [path1 path2 ...] [espressione]La ricerca viene effettuata solamente sui percorsi specificati. I percorsi vanno separati da spazio.
return
Nome e path dei file trovati
Espressioni
L’espressione descrive come vengono trovati i file, e quali azioni devono essere eseguiti su di essi.
Le espressioni sono composte da una sequenza di elementi:
- test: valutazione di una proprietà di un file, rende un valore booleano
- azioni: azioni da effettuare sui file trovati, ritornano true se hanno successo
- opzioni globali: influenzano l’esecuzione di test o azioni. Ritornano sempre true
- opzioni posizionali: influenzano solo le azioni o i test che seguono. Ritornano sempre true
Gli elementi di una espressione sono collegati da operatori:
- -o indica OR
- -a indica AND (se non specifichiamo un operatore, AND è implicito)
- ! per negare
Elementi
test
-name pattern # scrivere pattern tra apici '' (oppure usare il carattere di escape) per evitare che la shell espanda i metacaratteri tipo *
-type [dfl] # directory, regular file, symbolic link
-size [+-]n[ckMG] # n: quantità di spazio ckMG: unità di misura
-user user # user specficiato come username o UID, cerca per proprietario
-group group
-perm [-/]mode # -mode: almeno permessi indicati, /mode: almeno uno dei permessi, mode: tutti i permessiazioni
-delete # ritorna true in caso di successo (niente errori)
# SE SCRIVI -delete PRIMA DEI TEST VENGONO ELIMINATI TUTTI I FILE
-exec command ; # tutti gli argomenti specificati dopo command vengono considerati come argomenti, fino a ; (\;)
# la stringa {} è utilizzata per indicare il nome del file attualmente processato
# il comando viene eseguito a partire dal percorso di partenza del comando find
-execdir # per eseguire il comando a partire del path del file trovatoesempi
find path -perm/u=w,g=w # cerca file che possono essere scritti da almeno uno fra owner e group ownerlocate
locate [options] file1...Questo comando ricerca il/i file specificato/i.
Sfrutta un database aggiornamento periodicamente dal sistema (l’aggiornamento può essere forzato da updatedb, richiede privilegi di root).
Questo comando va installato sudo apt install plocate (lo suggerisce la shell se cercate di usarlo).
differenze rispetto a find
- find da sempre risultati aggiornati
- plocate va installato
- locate è più facile e veloce
- find permette di definire test e azioni
Ricerca di testo nei file
grep
Questo comando (general regular expression print) permette di cercare in uno o più file di testo le linee (righe) che corrispondono ad espressioni regolari o stringhe letterali.
grep [opzioni] [-e] modello [-e modello2] file1 [file2..]Se si vuole specificare più di un modello si deve utilizzare -e prima di ciascun modello incluso il primo.
| opzione | significato |
|---|---|
| -i | ignora le distinzioni fra maiuscole e minuscole |
| -v | mostra le linee che non contengono l’espressione |
| -n | mostra il numero di linea |
| -c | riporta solo il conteggio delle linee trovate |
| -w | trova solo parole intere |
| -x | linee intere |
regular expressions
È possibile specificare dove la stringa/espressione deve trovarsi all’interno di una riga:
'^' inizio della riga
'$' in fondo alla riga
# le parentesi quadre permettono di definire set di caratteri ammessi
grep '1[23]:[0-5][0-9]' file
'.' # indica qualsiasi carattere
'...cept' # può essere accept o except
'*' # indica che l'espressione che procede può essere ripetuta zero o più volte
'\' # è il carattere di escapeesempi
'^stringa$' # righe che contengono solo stringa
'^$' # righe vuoteArchiviazione e compressione
tar
Il comando tar (Tape ARchive) permette di archiviare/estrarre una raccolta di file e cartelle
tar modalità [opzioni] [file1...]Il formato del file creato dipende dalla compressione (eventualmente) utilizzata
- .tar no compr
- .tar.gz compresso con algoritmo gz
- .tar.bz2 compresso con algoritmo bzip2
modalità
| simbolo modalità | significato |
|---|---|
| A | aggiungi file tar all’archivio (aggiungi i file presenti dentro un tar in un altro archivio) |
| c | crea un nuovo archivio |
| d | trova le differenze fra l’archivio ed il file sysyem |
| —delete | cancella file dall’archivio |
| r | aggiungi file all’archivio |
| t | elenca i file di un archivio |
| U | aggiungi i file all’archivio, ma solo se differiscono dalla copia eventualmente già presente |
| x | estrai file dall’archivio |
opzioni
| simbolo modalità | significato |
|---|---|
| v | verbose |
| z | compressione con gzip |
| j | compressione con bzip2 |
| f | permette di specificare il nome dell’archivio |
gzip/gunzip e bzip2/bunzip2
Se si devono comprimere file o archivi creati precedentemente con tar, è possible utilizzare:
gzip file1 file2... # file elencati vengono compressi e salvati in file con lo stesso nome ed estensione .gz . I file non compressi vengono eliminati
gunzip file1.gz file2.gz .. # estrae i file compressi specificati in file con lo stesso nome(senza estensione relativa alla compressione). I file compressi, dopo essere stati estratti vengono eliminati
bzip2
bunzip2 # stessa roba ma con algoritmo bziLibrerie Standard
unistd.h
pid_t fork(void)
sys/types.h
stdio.h
stdlib.hPassaggio di parametri a programmi in C
Il main è come segue:
int main(int argc, char**argv)
// argc è il numero di argomenti
// argv è il vettore argomentiquando nel terminale eseguo:
./eseguibile argomento1 ... argomentoN- argv[0] è il comando eseguito
- argv[1] è il Path dal quale stiamo eseguendo
- da argv[2] in poi sono gli argomenti passati