2011-12-28 30 views
5

Tengo un script de shell más grande que maneja cosas diferentes.Shell Script y espacios en la ruta

Se obtendrá su propio lugar por la siguiente ...

BASEDIR=`dirname $0`/.. 
BASEDIR=`(cd "$BASEDIR"; pwd)` 

entonces se usará BASEDIR crear otras variables como

REPO="$BASEDIR"/repo 

Pero el problema es que este script no funciona si la ruta contiene espacios donde se ejecuta actualmente.

Entonces la pregunta es: ¿existe una buena solución para resolver ese problema?

+0

las que Shell está utilizando? – eaj

+0

Esto debería ser posix, porque debería ejecutarse en tantos unixes como sea posible ... Aquí puede ver el script que quiero decir (se usa como plantilla). http://svn.codehaus.org/mojo/trunk/mojo/appassembler/appassembler-maven-plugin/src/main/resources/org/codehaus/mojo/appassembler/daemon/script/unixBinTemplate – khmarbaise

+0

Ejecuté los comandos de arriba en ambos 'bash' y' dash' (lo que Ubuntu usa para 'sh'), en un directorio cuyo nombre de directorio padre tiene espacios. Parece que funciona bien. ¿Qué sucede si ejecuta los comandos desde un terminal en un directorio problemático, seguido de 'echo" $ REPO "'? Supongo que olvidó citar '" $ REPO "' en alguna parte. –

Respuesta

2

Cita la variable completa así:

REPO="$BASEDIR/repo" 
7

Asegúrese de que vuelva a citar cualquier cosa que pueda contener espacios:

BASEDIR="`dirname $0`" 
BASEDIR="`(cd \"$BASEDIR\"; pwd)`" 
1

funciona perfectamente bien para mí. ¿Cómo está usando REPO? ¿Qué específicamente "no funciona" para ti?

He probado

#!/bin/sh 
BASEDIR=`dirname $0`/.. 
BASEDIR=`(cd "$BASEDIR"; pwd)` 
REPO="$BASEDIR"/repo 
echo $REPO 

en un directorio ".../a/b c d". Emite ".../a b/repo", como se esperaba.

Indique el error específico que está recibiendo ... Un informe de error "no funciona" es el informe de error menos útil, y cada programador lo odia absolutamente.

1

El uso de espacios en los nombres de directorio en Unix es siempre un problema, por lo que si se pueden evitar mediante el uso de guiones bajos, esto evitará un comportamiento extraño de scripts.

estoy claro por qué se está configurando BASEDIR ser el directorio padre del directorio que contiene el script actual (..) y luego reiniciarlo después de cambiar a ese directorio

La ruta al directorio debería funcionar si tiene ..

por ejemplo /home/trevor/data/../repo

BASEDIR=`dirname $0`/.. 

Creo que si la función echo $ REPO debe tener asignado el camino correcto, ya que utiliza comillas cuando asignándole pero si a continuación, intenta utilizar $ REPO alguna parte más en el guión, necesitarás usar comillas dobles para eso también.

p. Ej.

#!/bin/ksh 

BASEDIR=`dirname $0`/.. 
$REPO="$BASEDIR"/repo 

if [ ! -d ["$REPO"] 
then 
    echo "$REPO does not exist!" 
fi 
1

marcas de uso del habla como abajo:

BASEDIR=`dirname "${0}"`/.. 
2

no hay manera confiable y/o portátil para hacer esto correctamente.

Ver How do I determine the location of my script? de por qué

La mejor respuesta es la siguiente, que todavía depende del sistema operativo

BASEDIR=$(readlink -f $0)

entonces usted puede hacer cosas como REPO="$BASEDIR"/repo, simplemente asegúrese de dar su variables como lo hiciste

5

La respuesta es "Citas en todas partes".

Si la ruta que ingresa tiene espacio, entonces dirname $0 fallará.

$ cat quote-test.sh 
#!/bin/sh 

test_dirname_noquote() { 
     printf 'no quotes: ' 
     dirname $1 
} 
test_dirname_quote() { 
     printf 'quotes: ' 
     dirname "$1" 
} 

test_dirname_noquote '/path/to/file with spaces/in.it' 
test_dirname_quote '/path/to/file with spaces/in.it' 

$ sh quote-test.sh 
no quotes: usage: dirname string 
quotes: /path/to/file with spaces 

Además, trate de este divertido ejemplo

#!/bin/sh 

mkdir -p /tmp/foo/bar/baz 
cd /tmp/foo 
ln -s bar quux 
cd quux 
cat >>find-me.sh<<"." 
#!/bin/sh 

self_dir="$(dirname $0)" 
base_dir="$((cd "$self_dir/.." ; pwd -P))" 
repo="$base_dir/repo" 

printf 'self: %s\n' "$self_dir" 
printf 'base: %s\n' "$base_dir" 
printf 'repo: %s\n' "$repo" 
. 

sh find-me.sh 

rm -rf /tmp/foo 

resultado cuando se ejecuta:

$ sh example.sh 
self: . 
base: /tmp/foo 
repo: /tmp/foo/repo 
Cuestiones relacionadas