I comandi per le ricerche dei file

10 / 100

La ricerca di uno specifico le all’interno del lesystem, o dei le con una certa serie di caratteri-stiche, e una operazione molto comune, e per questo sono stati sviluppati alcuni comandi molto essibili, che permettono di e ettuare le piu complesse tipologie di ricerca.

Un primo comando che si puo usare per cercare dei file è which, che ci indica a quale le eseguibile corrisponde un certo comando, facendo una ricerca nelle directory indicate nel PATH.

Una estensione di which, e il comando whereis che consente di estendere la ricerca e ricercare oltre ai binari eseguibili anche le pagine di manuale ed eventuali sorgenti associati ad un comando.

Il comando whereis prende come argomento il nome del le o comando da cercare, e stampa i risultati sullo standard output. Si possono restringere le ricerche soltanto a binari, pagine di manuale o sorgenti utilizzando rispettivamente le opzioni -b, -m e -s. Il comando prende il nome passato come argomento, elimina eventuali estensioni (ad esempio se si cerca un sorgente elimina il .c) ed esegue la ricerca in una serie di directory standard (elencate nella pagina di manuale). Si possono restringere le ricerche a delle directory speci che per binari, pagine di manuale e sorgenti usando rispettivamente le opzioni -B, -M e -S seguite dalle directory a cui restringere la ricerca. Per tutti i dettagli e l’elenco completo delle opzioni si consulti al solito la pagina di manuale.

Il comando piu veloce per cercare un le in maniera generica sul lesystem e locate, che, come suggerisce il nome, serve a localizzare sul lesystem tutti i le che contengono nel loro pathname la stringa passata come argomento. Il vantaggio di questo programma e la sua velocita, esso infatti non e ettua la ricerca con una scansione del contenuto del disco, ma su un piccolo database interno che contiene l’elenco di tutti i le presenti nel sistema. Di questo programma esistono diverse versioni che si sono succedute nel tempo, qui prenderemo in considerazione quella che viene fornita dal pacchetto mlocate, adottata da tutte le principali distribuzioni.

Il comando riconosce l’opzione -i, che richiede che venga e ettuata una ricerca case insensi-tive, e -e che richiede che sia verificata l’effettiva esistenza del file. Il comando inoltre consente l’uso come argomento di espressioni analoghe a quelle usate dalla shell per il filename globbing , se si usa l’opzione -r si potrà usare, come unico argomento, una espressione regolare.

Le altre opzioni e la descrizione completa del comando e al solito disponibile nella relativa pagina di manuale, accessibile con man locate.

Il fatto che locate si a di ad un database ci fa capire immediatamente anche i suoi limiti: anzitutto la ricerca puo essere e ettuata solo per nome, ed inoltre il comando sar in grado di e ettuare la ricerca solo sui le gia inseriti nel database. Questo viene creato ed aggiornato tramite il comando updatedb che in genere viene eseguito una volta al giorno fra i lavori periodici di cron per cui se un le e stato creato dopo l’ultimo aggiornamento non si potrà vederlo.

Il comando updatedb prende una serie di opzioni in forma estesa, che gli permettono di de nire quale le usare per il database, quali directory (ad esempio non ha molto senso indicizzare /tmp) e quali lesystem (non ha senso indicizzare un CDROM o un lesystem di rete) inserire nel database dei le e quali no.

La caratteristica di updatedb e che i valori di alcune opzioni possono essere impostate attraverso l’uso del le di configurazione, /etc/updatedb.conf.

Il file prevede che i valori siano assegnati in forma di assegnazione di un valore ad una variabile di shell, con i nomi delle variabili identici a quelli delle opzioni corrispon-denti, ma scritte in maiuscolo anziche minuscolo e senza il iniziale.

PRUNE_BIND_MOUNTS=”yes”
PRUNENAMES=”.git .bzr .hg .svn”

PRUNEPATHS=”/tmp /var/spool /media”

PRUNEFS=”NFS nfs nfs4 rpc_pipefs afs binfmt_misc proc smbfs autofs iso9660 ncpfs coda devpts ftpfs devfs mfs shfs sysfs cifs lustre_lite tmpfs usbfs udf fuse.glusterfs fuse.sshfs”

Allora, in corrispondenza con le omonime opzioni di tab. 2.13, con PRUNEFS si indicano i lesy-stem da non indicizzare, come quelli di rete, i lesystem virtuali come /proc o quelli di dispositivi estraibili mentre con PRUNEPATHS si indicano le directory da non indicizzare, come quelle dei le temporanei, gli spool delle code di stampa e della posta, ecc. L’opzione PRUNE_BIND_MOUNTS e invece un valore logico, che consente di eliminare le apparizioni duplicate degli stessi le che si trovano al di sotto dei eventuali bind mount

Un problema che si poneva con la prima versione di locate era che il comando restituiva tutte le voci indicizzate indipendentemente dai loro permessi, permettendo cos ad un utente normale di veri care la presenza di le per i quali non avrebbe accesso. Questo veniva risolto a livello di indicizzazione eseguendo quest’ultima per conto di un utente senza privilegi sul lesystem in modo da inserire nel database solo i le visibili pubblicamente, con la conseguenza pero che gli utenti non erano in grado di avere indicizzati i propri le privati. Per risolvere questo problema le versioni attuali del programma eseguono una indicizzazione generale e mostrano i risultati veri cando se i permessi dell’utente consentono l’accesso al le.

Per superare i limiti di locate e affini, si puo usare il comando find, che non utilizza un database, ma esegue la ricerca direttamente nel lesystem, al costo di una notevole attivit su disco, e di tempi di esecuzione decisamente piu lunghi. Si puo comunque ridurre il carico facendo e ettuare la ricerca su sezioni ridotte dell’albero dei le; il comando infatti prende come primo argomento la directory da cui iniziare la ricerca, che verra eseguita ricorsivamente in tutte le directory sottostanti; se non si speci ca nulla la ricerca partir dalla directory corrente.

Il comando supporta quattro categorie principali di opzioni, descritte da altrettante sezioni della pagina di manuale, accessibile al solito con man find. La prima categoria (descritta nella sezione OPTIONS) contiene le opzioni vere e proprie, che controllano il comportamento di find, la seconda, (descritta nella sezione TESTS) contiene le opzioni di ricerca che permettono di se-lezionare i le in base ad una loro qualunque proprieta (nome, tipo, proprietario, i vari tempi, permessi, ecc.), la terza (descritta nella sezione ACTIONS) contiene le opzioni che permettono di speci care una azione da eseguire per ciascun le che corrisponde alla ricerca, la quarta (de-scritta nella sezione OPERATORS) contiene le opzioni che permettono di combinare fra loro diverse selezioni.

Le opzioni generiche, le principali delle quali sono riportate in tab. 2.14, permettono di modi care il comportamento del comando, ad esempio con -maxdepth si puo limitare la ricerca ai primi livelli di sottodirectory, mentre con -mindepth la si puo far partire da un certo sottolivello. Inoltre con -L si puo richiedere che il comando risolva eventuali link simbolici, facendo riferimento ai le cui essi puntano anziche al link stesso, come avviene di default.

Le maggiori potenzialit di find derivano dalla sua capacit di e ettuare ricerche con i criteri piu svariati, da quelli sul nome del le in varie forme (con -name, -regex, -path), a quelli per gruppo e utente (con -group e -user), secondo i permessi (con -perm), secondo i vari tempi (-atime, -ctime, -mtime) per tipo di le, di lesystem su cui e il le, ecc. Un elenco delle principali opzioni di ricerca, con il relativo signi cato, e riportato in tab. 2.15.

Alcune di queste opzioni necessitano di alcuni chiarimenti, ad esempio con l’opzione -name si puo e ettuare la classica ricerca sul nome del le, con tanto di supporto per i caratteri jolly del lename globbing, che pero vanno adeguatamente protetti scrivendoli fra virgolette per evitarne l’espansione da parte della shell. La ricerca e e ettuata solamente sul nome del le cos come e scritto nella directory che lo contiene, e non sul suo pathname, se si vuole eseguire la ricerca su quest’ultimo occorre usare -path.

Per tutte le opzioni che prendono un valore numerico che si e indicato con \n“, come quelle sui tempi, gli identi catori, il numero di link, ecc. il comando permette una sintassi molto potente: speci cando solo il numero si richiede una corrispondenza esatta, precedendolo con il segno \” si richiede invece che il valore sia inferiore, mentre precedendolo con un \+” si richiede che sia superiore. In questo modo ad esempio, nel caso dei tempi, si puo richiedere che un le sia piu vecchio o piu giovane di un dato tempo. Per cui se si vogliono cercare i le modi cati negli ultimi 5 minuti si dovra dare il comando:

[email protected]:~/truedoc/corso$ find . -mmin -5

./shell.tex

mentre se si vuol cercare quelli non acceduti da piu di quindici giorni si fara:

[email protected]:~/truedoc/corso$ find . -atime +15

./ringraziamenti.tex

L’opzione di ricerca sui permessi -perm merita una trattazione a parte, il parametro mode passato all’opzione supporta infatti a sua volta una sintassi abbastanza complessa. Anzitutto un permesso puo essere espresso sia in forma simbolica, con lo stesso formato visto in sez. 1.4.3, ma usando solo \=” come operatore, che in forma numerica. Speci cando un valore find cer-chera un le che abbia esattamente quel valore per i permessi, ad esempio se si speci ca g=w corrisponderanno soltanto i le con un permesso numerico esattamente uguale a 020.

Dato che in genere non si e interessati alla ricerca di un valore speci co di tutti i permessi, quanto alla presenza di alcuni di essi, indipendentemente da quali possono essere gli altri, il valore puo essere speci cato apponendovi, in maniera simile a quanto si fa con i valori numerici, i due segni \” e \+“, in realt quest’ultimo e ormai deprecato, ed al suo posto occorre usare \/“. Trattandosi pero nel caso dei permessi di una maschera di bit, il signi cato di questi caratteri non puo essere come in precedenza relativo ad un valore numerico maggiore o minore di quello indicato, considerato poi che la notazione e valida anche per le espressioni simboliche.

Dato che un valore espresso senza segno richiede la corrispondenza esatta, si usano queste combinazioni per selezionare la presenza di uno o piu bit senza curarsi dello stato degli altri, che e in genere il tipo di ricerca piu utile. Se si usa il segno \” allora mode dovrà speci care, se si usa la forma simbolica, quali sono i permessi che devono essere presenti sul le, oppure se si usa la maschera dei bit quali si vuole che siano presenti i bit nulli e gli altri permessi verranno ignorati. Se invece si usa \/” la richiesta e piu debole ed il le corrisponde purche almeno uno dei permessi speci cati con il valore di mode sia attivo. In questo modo con -mode si puo richiedere una condizione in cui siano attivi un permesso \e” un altro, mentre con /mode una in cui siano attivi un permesso \o” un altro. Come accennato una seconda importante categoria di opzioni e quella relativa alle azioni; e possibile infatti, per ogni le che corrisponde al criterio di ricerca speci cato, far eseguire a find una certa azione. Se non si speci ca nulla l’azione di default e quella di stampare il nome del le, equivalente alla opzione -print; ma si possono anche scrivere i nomi su un le qualunque usando l’opzione -fprint file, o usare vari formati di stampa. Quella di gran lunga piu importante e -exec che permette di eseguire, per ogni le corrispondente alla selezione, un comando. La sintassi dell’opzione e complessa in quanto si deve inserire una riga di comando all’interno di un’altra, e ci sono delle convenzioni usate dal comando per passare i valori. Quando si usa -exec tutto quello che segue viene interpretato come una riga di comando no a che non si incontra un carattere \;“, in detta riga si puo fare riferimento al le che corrisponde con la stringa {}. Il problema e che tutti questi caratteri vengono interpretati dalla shell, e devono quindi essere adeguatamente protetti; allora se ad esempio si vogliono spostare tutti i le non acceduti da piu di 15 giorni in una directory old, si potra usare un comando del tipo:

find . -atime +15 -exec mv \{\} old \;

La potenza del comando find e poi ulteriormente aumentata dal fatto che le varie opzioni precedenti possono essere combinate fra di loro con degli operatori logici. Ma se il signi cato di -and o -or puo sembrare immediato nel caso di criteri di ricerca, diventa meno chiaro quando si ha a che fare con delle azioni. In realt infatti il comando associa un valore logico ad ogni opzione, e quando si esegue una selezione il valore e automaticamente vero, lo stesso vale per tutte le azioni, tranne -exec (e derivate come -ok) in cui il valore e vero se il comando ha uno stato di uscita nullo, e falso altrimenti.

Il funzionamento di un operatore come -and (che e sottinteso se si speci cano piu opzioni) e che la seconda opzione (sia questa di ricerca, che una azione) viene eseguita solo se la prima e vera. Viceversa con -or la seconda opzione viene eseguita solo se la prima e falsa. In ne -not nega il risultato di una opzione.

Nel caso si combinino opzioni di ricerca tutto questo e del tutto inin uente riguardo il risultato del comando, che e quello che ci si aspetta intuitivamente: entrambe le condizioni di ricerca devono essere soddisfatte per -and o solo una per -or, o si inverte la selezione con -not.

Le cose cambiano profondamente quando ci sono di mezzo delle azioni come -exec, perch in tal caso l’esecuzione della seconda opzione dipende dal risultato della prima: se si chiede di eseguire due comandi ad esempio le cose dipendono dal risultato di quello che si esegue per primo.

Per questo ad esempio speci care con -and piu comandi (o semplicemente scriverne piu di uno, dato che in tal caso il -and e sottinteso) non signi ca a atto che essi saranno eseguiti tutti: lo saranno solo se tutti hanno successo, se uno non ha successo i successivi non saranno eseguiti. Qualora si voglia essere sicuri di eseguire tutti i comandi in una lista si puo usare l’operatore \,” nel qual caso saranno eseguiti comunque tutti, ma si avr un valore nale corrispondente all’ultimo della lista.