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
|