¿Cuál es el punto del comando externo `cd`?

72

Como se menciona en esta excelente respuesta , los sistemas POSIX tienen un binario externo cdademás del shell incorporado. En OS X 10.8 es /usr/bin/cd. No puede usarlo como el incorporado cdya que sale inmediatamente después de cambiar su propio directorio de trabajo. ¿Para qué sirve?

kojiro
fuente
Tenga en cuenta que Ubuntu y CentOS (y, por lo tanto, presumiblemente Red Hat) no tienen /usr/bin/cd, solo el shell incorporado.
Keith Thompson el
1
/bin/cdSin embargo, mi Fedora 19 incluye .
slm
1
Debian (verifiqué varias versiones, incluidas las pruebas actuales) no tiene /bin/cdni /usr/bin/cd.
derobert
1
Supongo que eso hace que estos sistemas no sean estrictamente POSIX. Cómo todo el mundo. :)
kojiro

Respuestas:

65

Sirve principalmente para asegurarse de que el cofre de herramientas POSIX esté disponible tanto dentro como fuera de un shell (consulte la justificación POSIX para solicitarlos ).

Para cd, eso no es tremendamente útil, pero tenga en cuenta que cdcambia los directorios pero tiene otros efectos secundarios: devuelve un estado de salida que ayuda a determinar si puede acceder chdir()a ese directorio o no, y genera un mensaje de error útil que explica por qué no puede chdir()cuando no puedes

Ejemplo:

dirs_i_am_able_to_cd_into=$(find . -type d -exec cd {} \; -print)

Otro posible efecto secundario es el montaje automático de un directorio.

En algunos sistemas, la mayoría de los comandos externos para las construcciones de shell estándar se implementan como un enlace simbólico al mismo script que:

#! /bin/sh -
"${0##*/}" "$@"

Es decir, iniciar un shell y ejecutar el builtin en él.

Algunos otros sistemas (como GNU) tienen utilidades como verdaderos comandos ejecutables que pueden generar confusión cuando el comportamiento difiere de la versión incorporada del shell.

Stéphane Chazelas
fuente
3
+1 para la observación sobre efectos secundarios y mensajes de error. No siempre se explica bien a los nuevos usuarios que muchos modismos inteligentes en Unix provienen del uso cuidadoso de los efectos secundarios. Y las páginas del manual nunca han sido buenas para describir el panorama general.
RBerteig
Vino aquí de una pregunta similar sobre SO, ¿podría explicar a qué se refiere cuando dice "montaje automático de un directorio"?
incipiente
1
@ffledgling, ver en.wikipedia.org/wiki/Automounter
Stéphane Chazelas
1
Para desempaquetar un poco el pensamiento de Stéphane Chazelas: si necesita asegurarse de que un directorio automontable de hecho esté montado sin hacer ningún cambio en él y sin intentar leer ningún archivo, puede usar el cdcomando externo . Puede ser útil para monitorear la disponibilidad de un sistema de archivos remoto automontable, o tal vez antes de hacer algo crítico con uno.
telcoM
11

El hecho de un comando cd no está disponible orden interna se debe esencialmente a la POSIX requisito para todas las órdenes internas regulares para ser exigible por los comandos de la familia exec env, find, nice, nohup, timey xargscombinado con el hecho de que algunos de estos comandos no están siendo implementados como a sí mismos órdenes internas.

Sin embargo, eso no tiene mucho sentido, cdya que combinarlo con estos comandos no tiene sentido. Sin embargo, aquí hay ejemplos más o menos sostenibles:

find . -type d -exec cd {} \;
env HOME=/foo cd
jlliagre
fuente
2
Una serie de incorporados están realmente exentos de esa regla . Curiosamente, cd no es uno de ellos.
Kevin
55
@Kevin, escribí que es un requisito para todos los componentes regulares , los exentos son componentes especiales : break, :, continue, . , eval, exec, exit, export, readonly, return, set, shift, times, trap, unsetsería irrelevante como comandos externos, mientras que cdes un componente normal que tiene algunos casos de uso documentados como un comando.
jlliagre
1

Además de verificar si una ruta corresponde a un directorio accesible, el cdejecutable procesará y usará la CDPATHvariable, e imprimirá la ruta absoluta del directorio resuelto si se usó con éxito.

$ export CDPATH=/usr
$ echo bin lib | xargs -n 1 cd
/usr/bin
/usr/lib

Esto solo es muy útil ocasionalmente, pero ahorraría volver a implementar la misma lógica para buscar directorios coincidentes. Un caso de uso concreto es encontrar el primer directorio existente de un nombre particular bajo varios padres posibles.

cdtambién procesa OLDPWDpara cd -, pero eso es menos concretamente útil ya que la variable de entorno ya estaría disponible.

Michael Homer
fuente