Extraña diferencia entre pwd y / bin / pwd

15

Agregué un enlace simbólico al directorio actual con ln -s . aa. Si ejecuto cd aa, y después de eso ejecuté pwd, la respuesta es /home/sim/aa.

Pero si lo ejecuto /bin/pwdse imprime /home/sim(el directorio actual no ha cambiado).

¿De dónde viene esta diferencia?

usuario3581976
fuente

Respuestas:

17

En la mayoría de las conchas, incluida bash, pwdhay una concha incorporada:

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

Si lo usa /bin/pwd, debe usar la -Lopción para obtener el mismo resultado que el incorporado pwd:

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

Por defecto, /bin/pwdignora los enlaces simbólicos e imprime el directorio real.

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 función integrada pwdincluye el enlace simbólico de forma predeterminada, excepto que -Pse utiliza esa opción o que la -o physicalconfiguración interna está habilitada.

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.
Cuonglm
fuente
No estoy seguro de entender de dónde viene esas diferencias
user3581976
/bin/pwdignora el enlace simbólico por defecto, lee parte info pwdde mi respuesta: Imprime un nombre completamente resuelto para el directorio actual. Es decir, todos los componentes del nombre impreso serán nombres de directorio reales; ninguno será un enlace simbólico.
Cuonglm
@ user3581976: Vea mi actualizado para más claramente.
Cuonglm
¿Por qué hay un comando -L para pwd aunque está configurado de forma predeterminada? ¿Y el shell no usa el comando / bin / pwd para ejecutar pwd?
user3581976
2
@ user3581976: la imagen con la que comienza su shell set -o physical, ahora pwdes la -Popción de uso por defecto, si no tiene la -Lopción, ¿cómo imprime la ruta que contiene el enlace simbólico? Lea esto https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlpara saber qué set -o physicalhace.
Cuonglm
7

Es posible que un proceso interrogue al sistema de archivos para determinar su directorio de trabajo actual, utilizando un método que es un poco complicado para estar en el tema como respuesta a esta pregunta. Esto es lo que hacen el pwdprograma y la getcwdfunción de biblioteca. En los primeros días de Unix, eran las únicas formas de averiguar cuál era su directorio de trabajo. Aquí está la parte de la respuesta a su pregunta que no puedo encontrar en ninguna de las otras respuestas, ni siquiera en ningún otro lugar de este sitio (después de 42 segundos de búsqueda):

  • Cuando se inicia el shell, obtiene su directorio de trabajo actual (probablemente llamando getcwd).
  • A partir de entonces, cada vez que haces una cd, pushdo popd, la cubierta hace un seguimiento del directorio de trabajo utilizando las funciones de manipulación de cadenas. Por ejemplo,

    • Si su directorio de trabajo es /home/simy usted escribe cd .., el shell calcula que su directorio de trabajo es/home .
    • Si su directorio de trabajo es /home/simy usted escribe cd ., el shell calcula que su directorio de trabajo sigue siendo/home/sim .
    • Si su directorio de trabajo es /home/simy usted escribe cd aa, el shell calcula que su directorio de trabajo es /home/sim/aa, sin verificar si aahay un enlace simbólico.

    Hace esto para ahorrar el "costo" de las llamadas getcwd. Pero esto es una compensación, ya que puede dar lugar a información incorrecta.

  • los pwd comando (incorporado) simplemente muestra la noción recordada / calculada del shell de cuál es el directorio de trabajo.
  • Además, el shell coloca su noción recordada / calculada de lo que es el directorio de trabajo en la variable de entorno PWD, para la conveniencia de los procesos del usuario. Un proceso nunca debe basarse en esto si quiere información precisa.

Entonces, la conclusión es que el shell puede confundirse acerca de dónde está. Pero si escribe /bin/pwd, eso se ejecuta en un proceso separado que no tiene acceso a la noción del shell de qué es el directorio de trabajo, por lo que determina el directorio de trabajo verdadero en sí mismo, a la antigua usanza. (Excepción: el /bin/pwdprograma puede ver la variable de entorno PWD, y aparentemente lo hace cuando usted especifica -L). Aquí hay otro ejemplo de cómo puede confundirse el shell:

cd /home/sim/aa # Suponga que /home, /home/simy /home/sim/aa
# son todos directorios reales (no enlaces simbólicos).
pwd # Salida: /home/sim/aaque es correcta.
mv ../aa ../bb
pwd # Salida: /home/sim/aaque es incorrecta.
/bin/pwd # Salida: /home/sim/bbque es correcta.


Y, en caso de que no lo tenga claro, si escribe ln -s . aay cd aa, entonces, su directorio de trabajo actual no ha cambiado , más de lo que lo hace cuando escribe cd ., porque eso es esencialmente lo que está haciendo cuando escribe cd aa.

Scott
fuente
Gracias, muy buena respuesta, esto es lo que estaba esperando;)
user3581976
2
Esta respuesta parece un poco torcida . Hay más -Lque ahorrar costos , y $PWDes una variable de entorno definida por POSIX definida por el usuario, las aplicaciones de espacio de usuario probablemente deberían confiar en ella (lo que sea que eso signifique ...?) . De todos modos, aunque no soy fanático de los enlaces simbólicos, es prerrogativa del usuario indirecta en tantas direcciones locas como él o ella debería elegir con ellos, y de eso -Lse trata más que nada.
mikeserv
1
Esta debería ser la respuesta aceptada (los enlaces simbólicos no son el punto de la pregunta).
Thomas Dickey