Ottimizzare find con uno script Bash

23/03/23 | ~ 5 minuti

Il comando find è un valido alleato per la ricerca all'interno del file system ma, sebbene la sua potenza e velocità, ha una sintassi piuttosto macchinosa.
Per ovviare a questo aspetto ho elaborato un semplicissimo script per la shell Bash che facilita l'immissione di una query base.

Codice

#!/usr/bin/env bash   if [ $2 ]   then     sudo find $1 -iname $2 2>/dev/null   else     sudo find . -iname $1 2>/dev/null fi

Analisi

La prima riga è detta shebang e indica al sistema l'interprete dello script. In questo modo non è necessario specificare "bash" nel comando.

$1 e $2 sono (per default nel linguaggio di scripting di Bash) i parametri del comando.
Quando invochiamo uno script possiamo aggiungere delle opzioni aggiuntive (i parametri, appunto) che vengono registrate come variabili che hanno nome composto da numeri in ordine crescente (partendo da 1, il $ sta a denotare la natura di variabile).

Il codice racchiuso tra if [ ] (se), then (allora) e fi (if al contrario, per chiudere) è quello che viene eseguito solo se una determinata condizione specificata all'interno delle parentesi quadre viene rispettata.
Else (altrimenti) fa parte dell'if principale, ma traccia la strada da percorrere in tutti gli altri casi in cui la condizione venga meno.

Se $2 esiste (cioè dobbiamo aver digitato almeno due parametri), allora l'utente acquisisce i permessi di amministratore con sudo e chiede una ricerca ricorsiva con find a partire dalla cartella specificata nel primo parametro ($1).
La ricerca è limitata a file o cartelle che hanno il nome scritto nel secondo parametro ($2).
L'ultima parte della riga (2>/dev/null) è opzionale e serve a nascondere i messaggi di errore (lo standard error).
Altrimenti digitando solo un parametro ($1), questo assumerà il ruolo di nome (quello che nel then era assegnato ad $2) e la ricerca partirà dalla cartella attuale, che nei sistemi Unix-Like è indicata dal simbolo del punto.

Rendere lo script operativo

Per consuetudine la rappresentazione dei comandi avviene con il prefisso "$ ", che non va digitato nella shell.

Il codice mostrato va inserito in un file, con un editor di testo di vostra scelta. Potete salvare il file senza estensione, facciamo un esempio crendo un file con nome myfind, all'interno della vostra cartella home.

Una volta creato lo script, questo andrà reso eseguibile modificando i suoi permessi: $ cd $ chmod u+x myfind Da un terminale ci posizionamo nella cartella home con cd e permettiamo all'utente proprietario di eseguire il file in questione con chmod.

A questo punto dobbiamo rendere lo script individuabile dal sistema, a prescindere da quale posizione venga richiamato. Perché questo accada è necessario che il file si trovi in una delle cartelle specificate all'interno della variabile d'ambiente $PATH.

Stampiamo il contenuto di $PATH: $ echo $PATH La shell ci restituirà in risposta un output simile a questo: /usr/local/sbin:/usr/local/bin:/usr/bin Si tratta di un elenco di cartelle separato dai due punti.

Spostiamo lo script in una delle cartelle contenute nella variabile $PATH: $ sudo mv myfind /usr/local/bin Ci limitermo ad agire in questo modo: un movimento (mv per move) preceduto da sudo per scrivere in una cartella di sistema.

Esempi pratici

In fin dei conti si tratta comunque di find, ma implementato in maniera leggermente diversa.
Poniamo di avere un file prova (vi ho già detto che in Linux le estensioni hanno pochissima importanza?) da cercare, che si trova anch'esso nella home del vostro utente.

Se digitiamo: $ cd $ myfind prova Avremo come risultato la posizione del file (./prova), perché, avendo specificato solo un parametro (prova, che assume il valore di $1), la ricerca sarà effettuata all'interno della cartella corrente.

Se invece nel comando usiamo due parametri, abbiamo più possibilità.
Nel caso indicassimo . o /home/nomeutente o una cartella superiore come $1, avremmo comunque il file prova ($2) localizzato da find.
$ myfind . prova Con output: ./prova Nell'esempio otterremo un risultato analogo a quello avuto se avessimo omesso il punto .

Indicando un cartella completamente diversa e che non contiene la home, l'output sarà nullo. $ myfind /tmp prova Nessun risultato.