PS1 = '$ (pwd)' pourquoi cela fonctionne et pourquoi est-ce différent de PS1 = $ (pwd)

18

Pourquoi lorsque j'entre cette commande, l'invite change dans mon répertoire?

PS1='$(pwd)'

J'utilise des guillemets simples, ce qui signifie pas d'interpolation, alias echo '$(pwd)'—— →$(pwd)

En outre, disons que nous avons clarifié pourquoi cela fonctionne ... pourquoi cela fonctionne-t-il différemment de PS1=$(pwd) ? (pas de guillemets du tout)

Par différent, je veux dire que si j'utilise les guillemets, l'invite continuera de changer dans mon répertoire actuel pendant que je navigue dans le terminal. Mais si je n'utilise pas de guillemets, l'invite restera toujours le répertoire dans lequel j'étais lorsque j'ai entré la commande pour la première fois.PS1=$(pwd)

Pourquoi?

HashWizard
la source
2
Économisez quelques cycles CPU et utilisez l'équivalent PS1 = '$ PWD'
jlliagre

Réponses:

29

Lorsque vous affectez simplement une valeur à une variable, l' $(...)expression est évaluée sauf si elle est placée entre guillemets simples (ou avec barre oblique inversée). Pour comprendre, essayez de comparer ces deux:

A=$(pwd)
echo "$A"
B='$(pwd)'
echo "$B"

La valeur de Adevient immédiatement la chaîne /home/yourusernameet, évidemment, on ne se souvient pas d'où vient cette chaîne, elle reste la même même si vous changez de répertoire. BCependant, la valeur de devient la chaîne littérale $(pwd)sans être interprétée.

Maintenant, la valeur de PS1quelque chose de spécial se produit: chaque fois que l'invite est imprimée, certaines constructions spéciales sont interprétées, par exemple la substitution de commande $(...)est effectuée exactement comme elle s'est produite ci-dessus lors de l'affectation à la Avariable. Évidemment, si votre PS1contient la chaîne littérale de votre répertoire personnel (comme ci-dessus avec A), il n'y a aucun moyen que cela puisse changer. Mais s'il contient la chaîne $(pwd)(comme ci-dessus avec B), il est évalué chaque fois que l'invite est imprimée et donc votre répertoire réel est affiché.

egmont
la source
14

Dans bash et zsh, la valeur de PS1n'est pas utilisée comme invite telle quelle, elle subit quelques extensions. Les règles diffèrent pour les deux coquilles, mais dans les deux cas, l' une des étapes consiste à effectuer l' expansion du « dollar » (substitution variables, les substitutions de commandes, évaluation arithmétique) avec la même syntaxe que dans la syntaxe shell normale ( , , ou , , ) .$VARIABLE${VARIABLE}$(COMMAND)`COMMAND`$((EXPRESSION))$[EXPRESSION]

  • Dans bash, l'expansion du dollar est activée par défaut, mais peut être désactivée avec shopt -u promptvars.
  • Dans zsh, l'expansion du dollar est désactivée par défaut, mais de nombreuses personnes (et la plupart des cadres de configuration que vous trouverez sur le Web) l'activent setopt prompt_subst.

Lorsque l'expansion du dollar dans l'invite est activée, PS1='$(pwd)'définit la valeur PS1à 6 caractères $(pwd)et entraîne $(pwd)donc la substitution, et donc la pwdcommande à exécuter, chaque fois que le shell affiche une nouvelle invite. D'un autre côté, PS1=$(pwd)définit PS1quel que soit le répertoire de travail actuel du shell à l'époque. Si l'expansion du dollar était désactivée PS1='$(pwd)', l'invite serait la chaîne littérale $(pwd).

Notez qu'il existe des moyens plus pratiques d'obtenir le répertoire de travail à l'invite:

  • En bash, avec une barre oblique inversée telle que \w, qui abrège votre répertoire personnel ~et peut être tronquée en définissant PROMPT_DIRTRIM.
  • Dans zsh, avec un pourcentage d'échappement tel que %/ou%~ ( %/est le même que $PWD, %~abrège les répertoires personnels), qui peut avoir un paramètre de découpage.
  • Dans l'un ou l'autre shell (et dans tout autre shell de style Bourne), $PWDest équivalent à $(pwd): vous n'avez pas besoin d'exécuter un sous-processus pour obtenir le répertoire de travail courant.
Gilles 'SO- arrête d'être méchant'
la source
7

Parce que sans les guillemets, le $ (pwd) est évalué lorsque PS1 est défini. Avec les guillemets, l'évaluation de $ (pwd) est reportée jusqu'à ce que l'invite s'affiche.

Sans les guillemets, PS1 est défini sur le répertoire en cours au moment où PS1 est défini. Avec les guillemets simples, PS1 est défini sur $ (pwd), ce qui signifie qu'il évaluera et imprimera le répertoire actuel chaque fois que l'invite est affichée.

farhangfarhangfar
la source