Re: [Soci SLIP] lo so che è banale ...

Lucio lucio a sulweb.org
Dom 30 Set 2018 09:56:20 CEST


Il 28/09/18 20:50, Marco Papa ha scritto:
> ... ma sono a digiuno. Come trovo un package installato di cui non 
> conosco che parte del nome (esempio Skype) da command line su Ubuntu? 

In realtà è tutt'altro che banale. La forma corretta è:

$ apt-cache search --names-only .\*skype.\*

ma, con altissima probabilità (ma non certezza assoluta), funzionerà anche:

$ apt-cache search --names-only .*skype.*


Spiegazione:

1) apt-cache offre varie funzioni, fra cui "search" che esegue una 
ricerca full-text nel nome e negli altri campi dei pacchetti disponibili

2) l'opzione --names-only limita la ricerca ai nomi di pacchetti

3) l'espressione regolare .\*skype.\* è la parte più divertente (questo 
è il modo di divertirsi di certi smanettoni): il punto è una wildcard 
che significa "qualsiasi carattere". L'asterisco, diversamente da quanto 
molti smanettoni sono inclini a credere, nelle espressioni regolari non 
significa "qualsiasi cosa" come nelle wildcard della shell, bensì 
"qualsiasi numero di occorrenze del carattere che precede l'asterisco 
stesso". Dato che il carattere che precede, se usiamo la seconda forma, 
è il punto, che è una wilcard, i due assieme significano "qualsiasi 
numero di occorrenze di qualsiasi carattere".

Tuttavia nella forma corretta c'è anche la backslash fra il punto e 
l'asterisco. Se sfortunatamente si esegue la seconda forma del comando, 
mentre ci si trova in una cartella, che contiene almeno un file, il cui 
nome contiene la parola skype, allora senza backslash abbiamo un problema.

La shell è un termine generico che identifica il programma che 
interpreta i comandi che digitiamo (per estensione potremmo immaginare 
che identifichi la finestra di terminale, anche se questo è formalmente 
errato). La shell che usiamo su Ubuntu si chiama Bash, ma ce ne sono 
anche altre, che qui non ci interessano.

Bash, mentre interpreta i comandi che digitiamo e PRIMA di eseguirli, 
esegue alcune operazioni automatiche che di solito sono utili. Fra 
queste c'è la sostituzione delle wildcard con i nomi di files 
corrispondenti.

Come accennavo prima, l'asterisco è una wildcard della shell, ma noi non 
lo stiamo usando come tale, perché ci serve usarlo come carattere 
speciale delle espressioni regolari, in modo che apt-cache lo riceva 
tale e quale e lo consideri per quel che significa nel mondo delle 
espressioni regolari, ovvero "qualsiasi numero di occorrenze di quel che 
mi precede".

Purtroppo Bash la pensa diversamente e non è al corrente di questa 
nostra volontà (è solo un programma e come tutti i programmi non è 
dotato di intelligenza). Bash quindi fa quel che è programmata per fare, 
ovvero, per ogni asterisco, cerca nella cartella corrente dei nomi di 
files che coincidano con l'espressione wildcard. Se disgraziatamente 
nella cartella corrente ci fosse un file (o una cartella) il cui nome è

Bash sostituirebbe i due asterischi, perché l'espressione wilcard 
coinciderebbe con quel nome, ed il comando diventerebbe (a nostra insaputa):

apt-cache search --names-only .conversazioni.skype.2017

che ovviamente porterebbe a non trovare alcun pacchetto con quel nome. 
Da notare che Bash esegue questa sostituzione solo se esistono dei nomi 
di files coincidenti con la wildcard. Se non esistono, Bash non esegue 
alcuna sostituzione e lascia l'asterisco tale e quale.

Aggiungere la backslash serve a dire a Bash: "guarda che il carattere 
che segue la backslash stessa (cioè l'asterisco nel nostro caso), devi 
lasciarlo stare anche se normalmente lo considereresti un carattere 
speciale". In questo modo Bash sa che non deve toccare i due asterischi 
e si limita a rimuovere le backslash, perché sa che quelle sono lì 
apposta per dirle come comportarsi. In questo caso quindi il comando che 
invia, sempre ed indipendentemente dai files presenti, sarà

apt-cache search --names-only .*skype.*

e si otterrà sempre la ricerca desiderata.

Per chi è riuscito a seguirmi fin qui, lascio immaginare il divertimento 
di quando serve usare la backslash all'interno dell'espressione regolare...


Maggiori informazioni sulla lista Soci