2011-12-28 19 views
5

Ho uno script di shell più grande che gestisce cose diverse.Shell Script e spazi nel percorso

Si otterrà una propria posizione dal seguente ...

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

quindi BASEDIR verrà usato creare altre variabili come

REPO="$BASEDIR"/repo 

Ma il problema è che questo script di shell non funziona se il percorso contiene spazi in cui è attualmente eseguito.

Quindi la domanda è: esiste una buona soluzione per risolvere questo problema?

+0

quale shell stai usando? – eaj

+0

Questo dovrebbe essere posix, perché dovrebbe essere eseguito su quanti più unix possibile ... Qui puoi vedere lo script che intendo (è usato come modello). http://svn.codehaus.org/mojo/trunk/mojo/appassembler/appassembler-maven-plugin/src/main/resources/org/codehaus/mojo/appassembler/daemon/script/unixBinTemplate – khmarbaise

+0

Ho eseguito i comandi di cui sopra in sia 'bash' che' dash' (che Ubuntu usa per 'sh'), in una directory il cui nome della directory madre ha spazi. Sembra funzionare bene. Cosa succede se si eseguono i comandi da un terminale in una directory problematica, seguito da "echo" $ REPO "'? La mia ipotesi è che hai dimenticato di citare "$ REPO" 'da qualche parte. –

risposta

2

Citazione la variabile completa in questo modo:

REPO="$BASEDIR/repo" 
7

Assicurarsi di virgolette doppie tutto ciò che può contenere spazi:

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

funziona perfettamente bene per me. Come stai usando REPO? Cosa specificamente "non funziona" per te?

ho testato

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

in un ".../a b/c d" directory. Emette ".../a b/repo", come previsto.

Si prega di dare l'errore specifico che si sta ricevendo ... Un rapporto "non funziona" è il rapporto bug meno utile, e ogni programmatore lo odia assolutamente.

1

L'utilizzo di spazi nei nomi di directory in unix è sempre un problema, quindi se possono essere evitati usando caratteri di sottolineatura, ciò impedisce un sacco di strani comportamenti di scripting.

Sono poco chiaro il motivo per cui si sta impostando BASEDIR ad essere la directory padre della directory contenente lo script corrente (..) e poi ripristinarlo dopo aver cambiato in quella directory

Il percorso della directory dovrebbe ancora funzionare se ha ..

ad es. /home/trevor/data/../repo

BASEDIR=`dirname $0`/.. 

Penso che se si echo fuori $ REPO dovrebbe avere il percorso correttamente assegnato perché hai usato virgolette quando si assegnano, ma se si tenta di utilizzare $ REPO da qualche parte altrimenti nella sceneggiatura, dovrai usare anche le doppie virgolette.

ad es.

#!/bin/ksh 

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

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

marchi Usa discorso come qui sotto:

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

Non v'è alcun modo affidabile e/o portatile per farlo correttamente.

Vedi How do I determine the location of my script? sul motivo per cui

La migliore risposta è la seguente, che è ancora dipende dal sistema operativo

BASEDIR=$(readlink -f $0)

Quindi è possibile fare cose come REPO="$BASEDIR"/repo, tanto per essere sicuro di citare il variabili come hai fatto tu.

5

La risposta è "Virgolette ovunque".

Se il percorso in cui si passa ha uno spazio all'interno, quindi dirname $0 avrà esito negativo.

$ 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 

Inoltre, provare questo divertente esempio

#!/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 

Risultato quando lo si esegue:

$ sh example.sh 
self: . 
base: /tmp/foo 
repo: /tmp/foo/repo 
Problemi correlati