2011-08-25 15 views
14

Estoy trabajando en un script bash para crear una nueva carpeta en/tmp/usando el nombre de un archivo, y luego copio el archivo dentro de esa carpeta.nombre base con espacios en un script bash?

#!/bin/bash 

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

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

done 

Comportamiento:

cuando escribo en mymove "/home/me/downloads/my new file.zip" que muestra esto:

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

Tengo un montón de comillas alrededor de todo, así que no entiendo por qué esto no está funcionando como se esperaba .

Además, tengo el bucle de formulario allí en caso de que haya varios archivos. Quiero que se copien todos en la misma carpeta, según el nombre base del primer argumento.

Respuesta

12

En el caso donde la asignación es una sustitución de un solo comando no es necesario citar la sustitución del comando. El shell no realiza la división de palabras para asignaciones de variables.

MYBASENAME=$(basename "$1") 

es todo lo que se necesita. Usted debe entrar en el hábito de usar $() en lugar de acentos abiertos porque $() nidos con mayor facilidad (es POSIX, por cierto, y todos los proyectiles actuales son compatibles con ella..)

PS: usted debe tratar de no escritura fiesta guiones . Intente escribir shell scripts. La diferencia es la ausencia de bashisms, zshisms, etc. Al igual que para C, la portabilidad es una característica deseada de los scripts, especialmente si se puede lograr fácilmente. Su secuencia de comandos no utiliza bashisms, así que escribiría #!/bin/sh en su lugar. Para los recolectores de nitidez: Sí, lo sé, los viejos SunOS y Solaris /bin/sh no entienden $() pero el /usr/xpg4/bin/sh es un shell POSIX.

+0

noté que muchos de los scripts de shell predeterminados usan sh en lugar de bash.Todavía no puedo decir demasiada diferencia, excepto con cosas como 'echo \ c' para evitar que aparezca una nueva línea. gracias por los consejos y la respuesta útil. – cwd

+0

La forma portátil con echo \ c es usar 'printf' donde simplemente omite el' \ n' en la cadena de formato. Los bashisms más frecuentemente utilizados son el uso de variables de matriz, sintaxis no POSIX como '[[...]]' para pruebas, para bucles con 'for ((...))', y la construcción 'select' . – Jens

+0

Esto no funciona con bash enviado en mi león macosx (GNU bash, versión 3.2.48 (1) -lanzamiento (x86_64-apple-darwin11) – rjha94

4

El problema es que en $1

MYBASENAME="`basename $1`" 

no se cita. Use este lugar:

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

+1 para usar la forma $() de sustitución de comando. Gente a menos que esté realmente seguro de que va a utilizar un sistema que solo tiene el shell bourne, ¿por qué no actualizar su sintaxis tecnológica a los estándares de 1993 ;-)! Apuesto a que usas 'sed -i' sin pensarlo. Pero no encontrará 'sed -i' en sistemas que se basan en bourne shell, o en otros 100 gnu/linux-isms. Buena suerte a todos. shellter

0
MYBASENAME="`basename $1`" 

debería ser

MYBASENAME="`basename "$1"`" 

Envolver el $1 con comillas dobles "$1"

2

que se está perdiendo un conjunto de citas!

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

Eso solucionará su problema.

+0

Estás escribiendo un par de comillas y barras invertidas demasiado :-) – Jens

Cuestiones relacionadas