Escaping variable in script

1

Sto usando script.sh in un terminale Mavericks di OS X che contiene solo quanto segue:

echo ${1}
ls ${1}

Ora, quando chiamo ./script.sh "/Users/me/some\ directoy\ with\ whitespace/" , il comando echo stampa /Users/me/some\ directoy\ with\ whitespace/ , ma ls insiste ancora nel dividere tutto, quindi i risultati sono

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

Notare \ alla fine delle prime tre righe di errore. Come faccio a farlo correttamente?

(Sono consapevole che l'uso di entrambi "" e \ nell'argomento di input lascia la \ nella mia variabile, ma presumo che avrei bisogno di quelli.)

Ho anche provato a usare ./script.sh /Users/me/some\ directoy\ with\ whitespace/ senza virgolette, quindi a creare lo script

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

ma questo ha reso l'output echo non contenente alcun \ ora, e l'output ls assomiglia a questo:

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

Si noti che tutto ciò che ha fatto è stato aggiungere le virgolette senza sembrare capirle come sintassi.

È in qualche modo correlato al IFS (separatore di campo di input) poiché se faccio lo script

IFS=*
ls ${1}

ed eseguirlo come ./script.sh /Users/me/some\ directoy\ with\ whitespace/ , mi mostra correttamente il contenuto della directory specificata. Non sono sicuro del perché, però.

    
posta G. Bach 22.11.2014 - 00:42
fonte

2 risposte

2

Non hai bisogno delle parentesi graffe. Questo dovrebbe funzionare bene:

echo $1
ls "$1"

Non si desidera utilizzare i backslash e le virgolette nel nome della directory. Uno o l'altro dovrebbe andare bene.

    
risposta data 22.11.2014 - 02:10
fonte
1

Lo script corretto è

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

(Puoi iniziare con #!/bin/sh , se preferisci.)

La sintassi di bash e altre shell è un po 'strana. Potresti pensare che $var significhi "il valore di var ", ma non lo è. Significa "prendi il valore di var , dividilo in ogni sequenza di spazi bianchi (o più in generale, dividilo secondo il valore di IFS ) e interpreta ogni parte come un modello glob che, se corrisponde a qualsiasi file, viene sostituito dall'elenco di corrispondenze ". Sì, è un bel boccone, ed è per questo che dovresti sempre scrivere "$foo" . Metti sempre le virgolette sulle sostituzioni variabili a meno che tu non sappia perché devi lasciarle fuori. All'interno di virgolette doppie, il significato di "$foo" è "il valore della variabile foo ".

Vedi Perché il mio script di shell soffoca su spazi bianchi o altri caratteri speciali? per ulteriori discussioni su questo argomento.

Per invocare il tuo script, puoi utilizzare qualsiasi forma di citazione - ma 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/'

Se ./script.sh /Users/me/some\ directoy\ with\ whitespace/ non funziona con le virgolette nello script, allora non lo stai scrivendo in una shell bash. Non riesco a indovinare su quale altro potrebbe essere inserito. Oppure non hai testato con la versione dello script che pensavi di avere.

    
risposta data 16.12.2014 - 03:20
fonte

Leggi altre domande sui tag