Je suis en train de nettoyer tous mes fichiers de configuration afin de les rendre aussi lisibles que possible. Je cherchais un guide de style sur l'utilisation de guillemets lors de l'exportation de chemins dans, par exemple, un ~/.bashrc
fichier:
export PATH="/users/me/path:$PATH"
contre
export PATH=/users/me/path:$PATH
Le guide Google style Shell suggère d'éviter les guillemets pour les noms de chemin. En revanche, de nombreux dépôts de fichiers dotfiles populaires (tels que Zach Holman ici ) utilisent des guillemets. Y a-t-il des situations où il est avantageux d'utiliser des guillemets dans le chemin?
Pointe du chapeau à @ gniourf_gniourf et @ chepner pour leur aide.
tl; dr
Pour être sûr, double-quote: cela fonctionnera dans tous les cas, sur tous les shells POSIX.
Si vous souhaitez ajouter un chemin basé sur ~
, sélectivement laissez le ~/
sans guillemets pour vous assurer que ~
Est développé; par exemple: export PATH=~/"bin:$PATH"
. Voir ci-dessous pour les règles d'expansion de ~
Dans les affectations de variables.
Alternativement, utilisez simplement $HOME
Dans une chaîne simple entre guillemets:export PATH="$HOME/bin:$PATH"
REMARQUE: ce qui suit s'applique à bash
, ksh
et zsh
, mais PAS à ( principalement) des shells strictement POSIX conformes tels que dash
; ainsi, lorsque vous ciblez /bin/sh
, vous DEVEZ entre guillemets le RHS de export
.[1]
sh
, lorsque export
est utilisé, donc toujours entre guillemets.La raison pour laquelle vous pouvez vous en sortir sans les guillemets doubles dans ce cas est que affectation variable dans les shells POSIX-like interpréter leur RHS différemment que arguments passé à commandes, comme décrit dans section 2.9.1 de la spécification POSIX:
Plus précisément, même si initial Séparateur de mots est effectué, il n'est appliqué qu'aux non étendus (bruts) RHS ( c'est pourquoi vous faites avez besoin de citer avec des espaces/métacaractères en littéraux), et non à son résultats.
Ceci s'applique uniquement aux instructions d'affectation authentique du formulaire<name>=<value>
Dans tous Shells de type POSIX , c'est-à-dire s'il y a pas de nom de commande avant le nom de la variable; notez que cela inclut les affectations préfixées à une commande pour définir des variables d'environnement ad-hoc pour elle, par exemple, foo=$bar cmd ...
.
Les affectations dans le contexte d'autres commandes doivent toujours être entre guillemets , pour être sûr:
Avec sh
(dans un Shell (principalement) strictement conforme à POSIX tel que dash
) une affectation avec export
est traitée comme une commande régulière =, et la partie foo=$bar
est traitée comme le 1er argument au export
intégré et donc traitée comme d'habitude (sous réserve du fractionnement de Word du result, aussi).
(POSIX ne spécifie aucune autre commande impliquant une affectation de variable (explicite); declare
, typeset
et local
ne sont pas standard extensions ).
bash
, ksh
, zsh
, dans un écart compréhensible de POSIX, étendez également la logique d'affectation à export foo=$bar
et typeset/declare/local foo=$bar
. En d'autres termes: dans les commandes bash
, ksh
, zsh
, export/typeset/declare/local
Sont traitées comme affectations , afin que la citation ne soit pas strictement nécessaire .
dash
, qui a également choisi d'implémenter le non - POSIX local
builtin[2] , ne lui étend PAS la logique d'affectation; il est cependant cohérent avec son comportement export
.Les affectations passées à env
(par exemple, env foo=$bar cmd ...
) Sont également sujettes à expansion en tant qu'argument de commande et nécessitent donc des guillemets doubles - sauf dans zsh
.
env
agit différemment de export
dans ksh
et bash
à cet égard est dû au fait que env
est un external utility, alors que export
est un Shell intégré.zsh
fondamentalement diffère de celui des autres shells en ce qui concerne les références de variables non cotées). L'extension Tilde (~
) Se produit comme suit dans les instructions d'affectation authentique:
~
Devant être non cité, comme d'habitude, il n'est également appliqué que: ~
; par exemple.:foo=~ # same as: foo="$HOME"
~
démarre la chaîne ou est précédé d'un sans guillemets:
~
est suivi d'un sans guillemets/
.foo=~/bin # same as foo="$HOME/bin"
foo=$foo:~/bin # same as foo="$foo:$HOME/bin"
Exemple
Cet exemple montre que dans bash
, ksh
et zsh
, vous pouvez vous éloigner sans entre guillemets, même lorsque vous utilisez export
, mais Je ne le recommande pas.
#!/usr/bin/env bash
# or ksh or zsh - but NOT /bin/sh!
# Create env. variable with whitespace and other Shell metacharacters
export FOO="b:c &|<> d"
# Extend the value - the double quotes here are optional, but ONLY
# because the literal part, 'a:`, contains no whitespace or other Shell metacharacters.
# To be safe, DO double-quote the RHS.
export FOO=a:$foo # OK - $FOO now contains 'a:b:c &|<> d'
[1] Comme le souligne @gniourf_gniourf: utilisation de export
pour modifier la valeur de PATH
est facultative, car une fois qu'une variable est marquée comme exportée, vous peut utiliser une affectation régulière (PATH=...
) pour modifier sa valeur.
Cela dit, vous pouvez toujours choisir pour utiliser export
, afin de rendre explicite que la variable en cours de modification est exportée.
[2] @gniourf_gniourf indique qu'une future version du standard POSIX pourrait introduire le local
intégré.
J'ai utilisé ces réponses ci-dessus lors de la définition des noms de chemin d'accès à l'environnement dans un fichier docker .env, et j'ai obtenu un bit. Je mets cela ici pour quiconque cherche comment définir des variables d'environnement pour docker.
Docker compose lit les variables d'environnement à partir d'un fichier .env qui existe dans le même dossier que docker compose est exécuté comme indiqué ici https://docs.docker.com/compose/env-file.
Cependant, au lieu d'encapsuler la valeur entre guillemets, docker compose a besoin de la variable d'environnement définie sans guillemets, sauf si les guillemets font partie de la valeur. Encore une fois, comme indiqué dans l'url ci-dessus
Il n'y a pas de traitement spécial des guillemets (c'est-à-dire qu'ils feront partie de la VAL, vous avez été averti;)
J'essayais de définir NODE_PATH=./src
pour que les chemins absolus fonctionnent dans une application react déployée par docker, mais l'avaient écrite comme NODE_PATH="./src"
. Cet avertissement m'a sorti du trou de lapin de 4 heures.
test 123
est un nom de chemin d'accès valide sous UNIX. Essayer
PATH=test 123
Il renverra:
123: command not found
Ou même
export PATH=test 123
qui reviendra
bash export: `123': not a valid identifier
Répond-il à votre question?
Honnêtement, je ne suivrais pas ces guides de style de quatrième partie . Même si je suis étonné que même Google annonce de si mauvais conseils.
Je suivrais:
(à étendre soigneusement)