Étrange différence entre pwd et / bin / pwd


15

J'ai ajouté un lien symbolique vers le répertoire actuel avec ln -s . aa. Si j'exécute cd aa, et après cela pwd, j'exécute , la réponse est /home/sim/aa.

Mais si je l'exécute, /bin/pwdil s'affiche /home/sim(le répertoire actuel n'a pas changé).

D'où vient cette différence?

Réponses:


17

Dans la plupart des shells, y compris bash, pwdest un shell intégré:

$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd

Si vous utilisez /bin/pwd, vous devez utiliser l' -Loption pour obtenir le même résultat que intégré pwd:

$ ln -s . test
$ cd test && pwd
/home/cuonglm/test
$ /bin/pwd
/home/cuonglm
$ /bin/pwd -L
/home/cuonglm/test

Par défaut, /bin/pwdignore les liens symboliques et imprime le répertoire réel.

De info pwd:

`-L'
`--logical'
     If the contents of the environment variable `PWD' provide an
     absolute name of the current directory with no `.' or `..'
     components, but possibly with symbolic links, then output those
     contents.  Otherwise, fall back to default `-P' handling.

`-P'
`--physical'
     Print a fully resolved name for the current directory.  That is,
     all components of the printed name will be actual directory
     names--none will be symbolic links.

La fonction intégrée pwdinclut le lien symbolique par défaut, sauf que cette -Poption est utilisée ou que -o physicalla fonction intégrée est activée.

De man bash:

pwd [-LP]
              Print the absolute pathname of the  current  working  directory.
              The pathname printed contains no symbolic links if the -P option
              is supplied or the -o physical option to the set builtin command
              is  enabled.  If the -L option is used, the pathname printed may
              contain symbolic links.  The return status is 0 unless an  error
              occurs  while  reading  the  name of the current directory or an
              invalid option is supplied.

Je ne suis pas sûr de comprendre d'où viennent ces différences
user3581976

/bin/pwdignore le lien symbolique par défaut, lisez une partie info pwdde ma réponse: affichez un nom entièrement résolu pour le répertoire courant. Autrement dit, tous les composants du nom imprimé seront des noms de répertoire réels - aucun ne sera un lien symbolique.
cuonglm

@ user3581976: Voir ma mise à jour pour plus de clarté.
cuonglm

Pourquoi existe-t-il une commande -L pour pwd alors qu'elle est définie par défaut? Et le shell n'utilise-t-il pas la commande / bin / pwd pour exécuter pwd?
user3581976

2
@ user3581976: Image avec laquelle vous démarrez votre shell set -o physical, maintenant, pwdutilisez l' -Poption par défaut, si vous n'avez pas d' -Loption, comment imprimez-vous le chemin contient le lien symbolique? Lisez ceci https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlpour savoir ce que set -o physicalça fait.
cuonglm

7

Il est possible qu'un processus interroge le système de fichiers pour déterminer son répertoire de travail actuel, en utilisant une méthode un peu trop compliquée pour être sur le sujet comme réponse à cette question. C'est ce que font le pwdprogramme et la getcwdfonction de bibliothèque. Dans les premiers jours d'Unix, ils étaient les seuls moyens de découvrir quel était votre répertoire de travail. Voici la partie de la réponse à votre question que je ne trouve dans aucune des autres réponses, ni même ailleurs sur ce site (après 42 secondes de recherche):

  • Lorsque le shell démarre, il obtient son répertoire de travail actuel (probablement en appelant getcwd ).
  • Par la suite, chaque fois que vous faites cd, pushdou popd, la coquille garde la trace du répertoire de travail en utilisant les fonctions de manipulation de chaîne. Par exemple,

    • Si votre répertoire de travail est /home/simet que vous tapez cd .., le shell calcule que votre répertoire de travail l'est /home.
    • Si votre répertoire de travail est /home/simet que vous tapez cd ., le shell calcule que votre répertoire de travail est toujours /home/sim.
    • Si votre répertoire de travail est /home/simet que vous tapez cd aa, le shell calcule que votre répertoire de travail est /home/sim/aa- sans vérifier s'il aas'agit d'un lien symbolique.

    Cela permet d'économiser le «coût» de l'appel getcwd. Mais c'est un compromis, car cela peut entraîner des informations incorrectes.

  • La pwdcommande (intégrée) affiche simplement la notion mémorisée / calculée du shell de ce qu'est le répertoire de travail.
  • En outre, le shell met sa notion mémorisée / calculée de ce qu'est le répertoire de travail dans la variable d'environnement PWD, pour la commodité des processus utilisateur. Un processus ne doit jamais s'appuyer sur cela s'il veut des informations précises.

Donc, en fin de compte, le shell peut être confus quant à son emplacement. Mais si vous tapez /bin/pwd, cela s'exécute dans un processus distinct qui n'a pas accès à la notion du shell de ce qu'est le répertoire de travail, et donc il détermine le véritable répertoire de travail lui-même, à l'ancienne. (Exception: le /bin/pwdprogramme peut regarder la variable d'environnement PWD, et apparemment, il le fait lorsque vous spécifiez -L.) Voici un autre exemple de la façon dont le shell peut se confondre:

cd /home/sim/aa # Supposons que /home, /home/simet /home/sim/aa
# sont tous les vrais répertoires (pas les liens symboliques).
pwd # Sortie:, /home/sim/aace qui est correct.
mv ../aa ../bb
pwd # Sortie:, /home/sim/aace qui est incorrect.
/bin/pwd # Sortie:, /home/sim/bbce qui est correct.


Et, juste au cas où vous ne seriez pas clair à ce sujet, si vous tapez ln -s . aaet cd aa, votre répertoire de travail actuel n'a pas changé , pas plus qu'il ne le fait lorsque vous tapez cd .- car, c'est essentiellement ce que vous faites lorsque vous tapez cd aa.


Merci, très bonne réponse, c'est ce que j'attendais;)
user3581976

2
Cette réponse semble un peu tordue . Il y a plus à -Lde réduction des coûts - et $PWDest une variable d'environnement POSIX spécifié défini par l' utilisateur - les applications de l' espace utilisateur devrait probablement faire confiance (quoi que cela signifie ...?) . Quoi qu'il en soit, bien que je ne sois pas du tout fan des liens symboliques, c'est la prérogative de l'utilisateur d'indirect dans autant de directions folles qu'il ou elle devrait choisir avec eux - et c'est ce qui -Lest plus que tout.
mikeserv

1
Cela devrait être la réponse acceptée (les liens symboliques ne sont pas l'objet de la question).
Thomas Dickey
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.