1 votes

Variable d'échappement dans script

J'utilise script.sh dans un terminal OS X Mavericks contenant uniquement ce qui suit :

echo ${1}
ls ${1}

Maintenant, quand j'appelle ./script.sh "/Users/me/some\ directoy\ with\ whitespace/" la commande echo imprime /Users/me/some\ directoy\ with\ whitespace/ mais ls insiste toujours pour tout diviser, donc les résultats sont les suivants

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

Remarquez le \ à la fin des trois premières lignes d'erreur. Comment faire correctement ?

(Je suis conscient que le fait d'utiliser à la fois "" et le \ dans l'argument d'entrée laisse le \ dans ma variable, mais je suppose que j'en aurais besoin).

J'ai également essayé d'utiliser ./script.sh /Users/me/some\ directoy\ with\ whitespace/ sans les guillemets, puis en rendant le script

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

mais cela a rendu le echo ne contient pas de \ maintenant, et le ls La sortie ressemble à ceci :

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

Remarquez qu'il n'a fait qu'ajouter les guillemets sans sembler les comprendre comme une syntaxe.


C'est en quelque sorte lié à la IFS (séparateur de champ de saisie) car si je fais en sorte que le script

IFS=*
ls ${1}

et l'exécuter en tant que ./script.sh /Users/me/some\ directoy\ with\ whitespace/ il me montre correctement le contenu du répertoire spécifié. Mais je ne sais pas trop pourquoi.

2voto

Neil McKeown Points 348

Vous n'avez pas besoin des accolades. Cela devrait fonctionner parfaitement :

echo $1
ls "$1"

Vous ne devez pas utiliser de barres obliques inversées ni de guillemets dans le nom du répertoire. L'un ou l'autre devrait suffire.

1voto

staffan Points 3299

Le script correct est

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

(Vous pouvez commencer par #!/bin/sh à la place si vous préférez).

La syntaxe de bash et des autres shells est un peu bizarre. Vous pouvez penser que $var signifie "la valeur de var ", mais ce n'est pas le cas. Cela signifie "prendre la valeur de var en le divisant à chaque séquence d'espacement (ou plus généralement, en le divisant selon la valeur de la variable IFS ), et interprète chaque partie comme un motif global qui, s'il correspond à un fichier, est remplacé par la liste des correspondances". Oui, c'est assez long - c'est pourquoi vous devriez toujours écrire "$foo" à la place. Mettez toujours des guillemets autour des substitutions de variables, sauf si vous savez pourquoi vous devez les omettre. À l'intérieur des guillemets doubles, la signification de "$foo" est "la valeur de la variable foo ".

Voir Pourquoi mon shell script s'étouffe-t-il sur les espaces ou autres caractères spéciaux ? pour une discussion plus approfondie sur ce sujet.

Pour invoquer votre script, vous pouvez utiliser toute forme de citation - mais une seule :

./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/ ne fonctionne pas avec les guillemets dans le script, alors vous ne le tapez pas dans un shell bash. Je ne peux pas deviner dans quoi d'autre vous pourriez le taper. Ou alors vous n'avez pas testé avec la version du script que vous pensiez avoir.

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X