erlug
[Top] [All Lists]

Re: [Erlug] selezione "inversa" + piccolissimo OT

To: ERlug - Lista Pubblica <erlug@xxxxxxxxxxxxxx>
Subject: Re: [Erlug] selezione "inversa" + piccolissimo OT
From: Davide Brini <db72@xxxxxxxxxxxx>
Date: Mon, 22 Dec 2008 17:14:49 +0100
On Monday 22 December 2008, 15:47, Piccinini Luca wrote:
> > Il problema piu' serio e' che la shell fa word splitting sul
> > risultato:
> >
> > $ ls -1
> > file1
> > file 1.mp3
> > file2
> > file 2.mp3
> > $ rm $(ls -b | grep '\.mp3$')
> > rm: cannot remove `file\\': No such file or directory
> > rm: cannot remove `1.mp3': No such file or directory
> > rm: cannot remove `file\\': No such file or directory
> > rm: cannot remove `2.mp3': No such file or directory
>
> Ok ho capito, ma mi risultava difficile da capire senza provare....
> anche perchè non ho ancora capito coa lo fa strippare, in quanto:
> rm 1\ .mp3  -  funziona
> rm `ls -b | grep mp3`  -  come fai notare non va, ma a livello logico
> dovrebbe in realtà essere lo stesso comando.... non capisco.... ma mi
> adeguo...

Premesso che il problema originario era trovare i file NON mp3, quindi il 
grep sarebbe -v, ma comunque questo e' cio' che accade (preso alla 
lontana):

$ ls -1
file con spazi
$ name="file con spazi"

se ora faccio

$ rm $name

la shell sostituisce a $name il suo valore, quindi la riga di comando 
diventa 

$ rm file con spazi

poi la shell esegue la divisione in parole (word splitting), in base al 
valore di IFS (che di default e' "spazio, tab, newline"): ogni 
occorrenza di una sequenza di caratteri compresi in IFS viene 
considerata un separatore di parola. Dopo di questo, la shell e' in 
grado di capire quale parte della riga e' il comando e quali sono gli 
argomenti, nell'esempio il comando sarebbe "rm" con tre 
argomenti: "file", "con", "spazi" che vengono passati a rm. Siccome file 
con quei nomi non esistono, viene restituito un errore (anzi, tre 
errori). (BTW, in questo caso per evitare il problema basta mettere tra 
doppi apici il nome della variabile: rm "$name")

La stessa cosa sopra accade se, anziche' usare una variabile, usiamo il 
risultato di un comando con `...` oppure $(...): il risultato del 
comando viene esaminato e la shell fa word splitting. Quindi nel mio 
primo esempio (nell'altra mail), 

ls -b | grep mp3

ritorna questo:

file\ 1.mp3
file\ 2.mp3

la shell cerca in questo risultato i caratteri spazio o tab o newline, e 
divide in parole. Quindi qui avremmo 4 parole (che diventano argomenti 
di rm):

file\
1.mp3
file\
2.mp3

da cui gli errori. Il problema qui NON si puo' risolvere usando i doppi 
apici, perche' quello evita si' che la shell faccia word splitting, ma 
proprio per questo il risultato del comando che sta tra "$(...)" diventa 
un SINGOLO argomento per rm, che ovviamente anche in quel caso protesta:

$ rm "$(ls -b | grep mp3)"
rm: cannot remove `file\\ 1.mp3\nfile\\ 2.mp3': No such file or directory

<Prev in Thread] Current Thread [Next in Thread>