Pourquoi mkdir échoue (aucun fichier ou répertoire) dans un script avec BIN_DIR = “~ / bin /”?

Réponses:

11

Le message d'erreur est généré parce que le tilde ~est cité, comme décrit dans la réponse de Zanna . Si vous souhaitez utiliser le ~, la partie pertinente du script doit être:

BIN_DIR=~/bin/

Si pour une raison quelconque vous souhaitez citer la chaîne, vous pouvez utiliser la variable d'environnement $HOME:

BIN_DIR="$HOME/bin/"

À mon avis, la deuxième approche est une meilleure pratique.

pa4080
la source
6
Il n'y a rien de mal à utiliser des ~scripts. cela fonctionne exactement de la même manière que dans la ligne de commande. Le problème est que la citation bloque l'expansion du tilde comme expliqué dans la réponse de Zanna .
terdon
@terdon, je suis d'accord. Mais je n'ai pas dit qu'il y avait quelque chose de mal, mais c'est une meilleure idée, car vous devriez faire moins attention.
pa4080
5
Mais il n'y a absolument aucune différence entre la ligne de commande et un script ici. Le fait que ce soit dans un script est complètement hors de propos, vous auriez exactement la même erreur dans la ligne de commande. Le problème est la citation, pas que ce soit dans un script.
terdon
Bien que cela soit tout à fait vrai, il est également juste d'utiliser des $HOMEscripts dans les scripts.
dessert
3
@ pa4080 Pouvez-vous ajouter une explication de la raison pour laquelle vous pensez qu'il est préférable de développer $HOMEque d'utiliser l'extension tilde? La seule explication que vous avez donnée est de dire: "c'est une meilleure idée, car vous devriez faire moins attention". Je n'ai aucune idée de ce que ça veut dire. Pouvez-vous l'exposer dans un montage? Sans elle, rien ne vient étayer votre réponse, alors elle y appartient sûrement. L'expansion de Tilde est requise par POSIX depuis un certain temps maintenant et la ligne de hachage du script est #!/bin/bashdonc je suppose que la portabilité n'est pas la raison.
Eliah Kagan
23

Cela ne fonctionne pas car ~est cité. Les guillemets doubles " suppriment l' expansion du tilde . Il n'y a pas de répertoire avec le nom littéral ~/bin. Comme expliqué dans man bash(souligné par moi):

Expansion Tilde

Si un mot commence par un caractère tilde sans guillemets (`~ '), tous les caractères précédant la première barre oblique sans guillemets (ou tous les caractères, s'il n'y a pas de barre oblique sans guillemets) sont considérés comme un préfixe tilde. Si aucun des caractères du préfixe tilde n'est cité, les caractères du préfixe tilde suivant le tilde sont traités comme un nom de connexion possible. Si ce nom de connexion est la chaîne nulle, le tilde est remplacé par la valeur du paramètre shell HOME. Si HOME n'est pas défini, le répertoire personnel de l'utilisateur exécutant le shell est remplacé à la place. Sinon, le préfixe tilde est remplacé par le répertoire personnel associé au nom de connexion spécifié.

Vous pouvez supprimer les guillemets , car ~c'est le seul caractère du chemin ~/binqui fera que le shell effectuera une expansion, et nous voulons l'expansion dans ce cas. Le shell n'effectuera pas d'autres extensions sur le résultat de l'expansion de tilde, au moins dans Bash 4 , que toutes les versions actuelles ou à distance d'Ubuntu ont . Donc, même si votre répertoire personnel contient des caractères inhabituels comme des espaces, ce n'est pas grave.

Ou vous pouvez utiliser à la $HOMEplace de ~, car l' expansion des paramètres n'est pas supprimée par des guillemets doubles, uniquement par des guillemets simples . Les guillemets doubles ne garantissent que la valeur étendue n'est pas elle - même soumise à des extensions supplémentaires, donc la séparation de mots ou extension de nom de fichier ne se produira pas. Fonctionne donc $HOMEmême avec les répertoires de départ aux noms étranges, aussi longtemps que vous conservez les guillemets doubles.

Zanna
la source
Selon cette déclaration, "l'expansion des paramètres n'est pas supprimée par des guillemets doubles, mais uniquement par des guillemets simples" : la sortie de cd '~'is -bash: cd: ~: No such file or directory.
pa4080
2
@ pa4080 L'expansion de ~ne fait pas partie de l'expansion des paramètres.
Barmar