2011-08-25 20 views
14

Sto lavorando ad uno script bash per creare una nuova cartella in/tmp/usando il nome di un file, e quindi copiare il file all'interno di quella cartella.basename con spazi in uno script bash?

#!/bin/bash 

MYBASENAME="`basename $1`" 
mkdir "/tmp/$MYBASENAME" 

for ARG in "[email protected]" 
    do 
     mv "$ARG" "/tmp/$MYBASENAME" 

done 

Comportamento:

Quando digito in mymove "/home/me/downloads/my new file.zip" lo dimostra questo:

mkdir /tmp/my 
new 
file.zip 
mv: rename /home/me/downloads/my new file.zip to /tmp/my\nnew\nfile.zip: 

Ho un sacco di virgolette intorno tutto, quindi non capisco perché questo non funziona come previsto .

Inoltre, ho il ciclo di moduli in là nel caso ci siano più file. Voglio che vengano copiati tutti nella stessa cartella, in base al basename del primo argomento.

risposta

12

Nel caso in cui l'assegnazione sia una sostituzione di comando singola non è necessario citare la sostituzione di comando. La shell non esegue la suddivisione in parole per assegnazioni di variabili.

MYBASENAME=$(basename "$1") 

è tutto ciò che serve. Si dovrebbe prendere l'abitudine di usare $() invece di apici inversi perché $() nidi più facilmente (è POSIX, btw, e tutte le shell moderni supportano..)

PS: Si dovrebbe cercare di non scrittura bash script . Prova a scrivere gli script shell. La differenza è l'assenza di bashismi, zismi, ecc. Proprio come per C, la portabilità è una caratteristica desiderata degli script, specialmente se può essere raggiunta facilmente. Il tuo script non usa alcun bashismo, quindi scriverei #!/bin/sh. Per i pignoli: Sì, lo so, i vecchi SunOS e Solaris /bin/sh non comprendono $() ma lo /usr/xpg4/bin/sh è una shell POSIX.

+0

ho notato che molti script di shell predefiniti usano sh invece di bash.Non riesco ancora a distinguere troppo la differenza, ad eccezione di cose come 'echo \ c' per impedire la visualizzazione di una nuova riga. grazie per i suggerimenti e la risposta utile. – cwd

+0

Il modo portatile con echo \ c è di usare 'printf' dove si omette semplicemente' \ n' nella stringa di formato. I bashismi più usati sono probabilmente l'uso di variabili di matrice, sintassi non POSIX come '[[...]]' per test, per cicli con 'for ((...))', e il costrutto 'select' . – Jens

+0

Questo non funziona con bash spedito su macosx lion (GNU bash, versione 3.2.48 (1) -release (x86_64-apple-darwin11) – rjha94

4

Il problema è che in $1

MYBASENAME="`basename $1`" 

non è citato. Usare questo invece:

MYBASENAME="$(basename "$1")" 
+2

+1 per l'uso della forma $() di sostituzione di comando. Gente a meno che tu non sia realmente, davvero sicuro che userai un sistema che ha solo la shell boreale, perché non aggiorni la sintassi della tua tecnologia agli standard del 1993 ;-)! Scommetto che usi 'sed -i' senza pensarci. Ma non troverai 'sed -i' su sistemi che si basano su bourne shell, o su 100 altri gnu/linux-ismi. Buona fortuna a tutti. shellter

0
MYBASENAME="`basename $1`" 

dovrebbe essere

MYBASENAME="`basename "$1"`" 

Avvolgere il $1 con virgolette "$1"

2

vi state perdendo una serie di citazioni!

MYBASENAME="`basename \"$1\"`" 

Questo risolverà il problema.

+0

Stai scrivendo un paio di virgolette e rovesci troppo :-) – Jens

Problemi correlati