Variable de escape en el script

1

Estoy usando script.sh en un terminal de OS X Mavericks que contiene solo lo siguiente:

echo ${1}
ls ${1}

Ahora, cuando invoco a ./script.sh "/Users/me/some\ directoy\ with\ whitespace/" , el comando echo imprime /Users/me/some\ directoy\ with\ whitespace/ , pero ls todavía insiste en dividir todo, por lo que los resultados son

ls: /Users/me/some\: No such file or directory
ls: directoy\: No such file or directory
ls: with\: No such file or directory
ls: whitespace/: No such file or directory

Observe el \ al final de las primeras tres líneas de error. ¿Cómo hago esto correctamente?

(Soy consciente de que usar tanto "" como \ en el argumento de entrada deja la \ en mi variable, pero supongo que los necesitaría).

También intenté usar ./script.sh /Users/me/some\ directoy\ with\ whitespace/ sin las comillas, luego hice el script

echo ${1}
ls "${1}"

pero eso hizo que la salida echo no contenga \ ahora, y la salida ls se ve así:

ls: "/Users/me/some\: No such file or directory
ls: directoy\: No such file or directory
ls: with\: No such file or directory
ls: whitespace/": No such file or directory

Observe que todo lo que hizo fue agregar las citas sin que parezca que las entienden como sintaxis.

Se relaciona de alguna manera con el IFS (separador de campo de entrada) ya que si hago el script

IFS=*
ls ${1}

y ejecutarlo como ./script.sh /Users/me/some\ directoy\ with\ whitespace/ , me muestra correctamente el contenido del directorio especificado. Aunque no estoy seguro de por qué.

    
pregunta G. Bach 22.11.2014 - 00:42

2 respuestas

2

No necesitas las llaves. Esto debería funcionar bien:

echo $1
ls "$1"

No quieres usar barras invertidas y comillas en el nombre del directorio. Uno u otro debe estar bien.

    
respondido por el miken32 22.11.2014 - 02:10
1

El script correcto es

#!/bin/bash
echo "${1}"
ls "${1}"

(Puedes comenzar con #!/bin/sh en su lugar si lo prefieres)

La sintaxis de bash y otros shells es un poco rara. Podría pensar que $var significa "el valor de var ", pero no lo hace. Significa “tomar el valor de var , dividirlo en cada secuencia de espacios en blanco (o, más generalmente, dividirlo según el valor de IFS ), e interpretar cada parte como un patrón global que, si coincide con cualquier archivo, Se sustituye por la lista de coincidencias ”. Sí, eso es un bocado, por lo que siempre debes escribir "$foo" en su lugar. Coloque siempre comillas dobles alrededor de las sustituciones de variables, a menos que sepa por qué necesita omitirlas. Dentro de las comillas dobles, el significado de "$foo" es "el valor de la variable foo ".

Consulte ¿Por qué ¿Mi script de shell se ahoga con los espacios en blanco u otros caracteres especiales? para una discusión más detallada sobre este tema.

Para invocar su script, puede utilizar cualquier forma de cotización, pero solo una:

./script.sh /Users/me/some\ directoy\ with\ whitespace/
./script.sh "/Users/me/some directoy with whitespace/"
./script.sh '/Users/me/some directoy with whitespace/'

Si ./script.sh /Users/me/some\ directoy\ with\ whitespace/ no funciona con las comillas en el script, entonces no estás escribiendo eso en un shell bash. No puedo adivinar qué más podrías estar escribiendo. O, si no, no probaste con la versión del script que pensabas que tenías.

    
respondido por el Gilles 16.12.2014 - 03:20

Lea otras preguntas en las etiquetas