2013-05-23 13 views
14

Il mio script di bash riceve un nome file (o percorso relativo) come stringa, ma deve quindi leggere da quel file. Posso solo leggere da un nome di file se lo dichiaro come letterale direttamente nello script (senza virgolette) ... il che è impossibile per gli argomenti poiché sono implicitamente le stringhe per cominciare. Osservare:bash: interpreta la variabile di stringa come nome file/percorso

a="~/test.txt" 
#Look for it 
if [[ -a $a ]] ; then 
    echo "A Found it" 
else 
    echo "A Error" 
fi 
#Try to use it 
while read line; do 
    echo $line 
done < $a 

b='~/test.txt' 
#Look for it 
if [[ -a $b ]] ; then 
    echo "B Found it" 
else 
    echo "B Error" 
fi 
#Try to use it 
while read line; do 
    echo $line 
done < $b 

c=~/test.txt 
#Look for it 
if [[ -a $c ]] ; then 
    echo "C Found it" 
else 
    echo "C Error" 
fi 
#Try to use it 
while read line; do 
    echo $line 
done < $c 

RENDIMENTI:

A Error 
./test.sh: line 10: ~/test.txt: No such file or directory 
B Error 
./test: line 12: ~/test.txt: No such file or directory 
C Found it 
Hello 

Come detto sopra, non riesco a passare un argomento riga di comando per le routine di cui sopra in quanto ottengo lo stesso comportamento che ho sulle stringhe tra virgolette.

+3

"~/test.txt" e "~/test.txt" interrompono l'espansione di ~ nella tua home directory. ~/test.txt funziona perché non è quotato. Smetti di usare la notazione ~ o smetti di usare virgolette .... –

+1

Se usi solo l'argomento della riga di comando dello script ('$ 1'), allora tutto funzionerà bene perché l'espansione della directory home sarà già stata eseguita prima che lo script venga chiamato. – rici

+0

@rici Sì, a condizione che '~' non sia quotato quando il suo script viene chiamato dalla riga di comando o da un altro script. È una storia diversa quando il suo script viene chiamato da un altro programma che passa _a literal_ '~' Questo sarebbe un errore che dovrebbe essere corretto nell'altro programma; ma se vuole affrontare un caso del genere nella sua sceneggiatura, probabilmente ha bisogno di "valutazione". – Uwe

risposta

28

Questo è parte delle regole di ~ -expansion. Nel manuale di Bash è chiaramente indicato che questa espansione non viene eseguita quando viene quotato lo ~.

Soluzione 1

Non citare il ~.

file=~/path/to/file 

Se è necessario citare il resto del nome del file:

file=~/"path with spaces/to/file" 

(Questo è perfettamente legale in un guscio di giardino-varietà.)

Soluzione 2

Usa $HOME invece di ~.

file="$HOME/path/to/file" 

BTW: Shell tipi di variabili

ti sembra di essere un po 'confuso circa i tipi di variabili di shell.

Tutto è una stringa.

Ripetere fino a quando non affonda in: Tutto è una stringa. (Tranne interi, ma sono hack principalmente sulla parte superiore di stringhe e array per quanto ne so, ma sono gli array di stringhe ..)

Questa è una stringa shell: "foo". Quindi è "42". Quindi è 42. Quindi è foo. Se non hai bisogno di citare le cose, è ragionevole non farlo; chi vuole digitare "ls" "-la" "some/dir"?

+0

'file = ~"/percorso con spazi/a/file "' non funziona troppo. È necessario scrivere 'file = ~ /" percorso con spazi/a/file "' – sercxjo

+1

@sercxjo per me funziona su zsh e non funziona su bash. Cioè '~ /" 'è più portabile. –

+1

@sercxjo (e Nick) corretto – michaelb958

Problemi correlati