¿Cuál es la diferencia entre los comandos incorporados cd y cd?

Respuestas:

41

El cdcomando está integrado, por lo que normalmente builtin cdhará lo mismo que cd. Pero hay una diferencia si cdse redefine como una función o un alias, en cuyo caso cdllamará a la función / alias pero builtin cdaún cambiará el directorio (en otras palabras, mantendrá el acceso incorporado incluso si está bloqueado por una función).

Por ejemplo:

user:~$ cd () { echo "I won't let you change directories"; }
user:~$ cd mysubdir
I won't let you change directories
user:~$ builtin cd mysubdir
user:~/mysubdir$ unset -f cd  # undefine function

O con un alias:

user:~$ alias cd='echo Trying to cd to'
user:~$ cd mysubdir
Trying to cd to mysubdir
user:~$ builtin cd mysubdir
user:~/mysubdir$ unalias cd  # undefine alias

El uso builtintambién es una buena manera de definir una cdfunción que hace algo y cambia el directorio (ya que llamar cddesde él simplemente seguiría llamando a la función nuevamente en una recursión sin fin).

Por ejemplo:

user:~ $ cd () { echo "Changing directory to ${1-home}"; builtin cd "$@"; }
user:~ $ cd mysubdir
Changing directory to mysubdir
user:~/mysubdir $ cd
Changing directory to home
user:~ $ unset -f cd  # undefine function
filbranden
fuente
55
+1 Los ejemplos son particularmente ilustrativos aquí.
Tashus el
2
En el caso de un alias, ¿hay alguna diferencia entre builtin cd mysubdiry \cd mysubdir?
gerrit
2
@gerrit Solo si hay una función nombrada cd, en cuyo caso \cdomitiría el alias y ejecutaría la función. Ver stackoverflow.com/a/16506263/4518341
wjandrea
15

En la mayoría de los casos, no hay diferencia (pero ver más abajo). El cdcomando es un comando incorporado en todos los shells. Debe estar integrado en 1 ya que un comando externo no puede cambiar el entorno del shell de invocación, y cambiar el directorio de trabajo constituye un cambio en su entorno.

El bashcomando builtinobliga al shell a utilizar la versión integrada de un comando, aunque puede haber una función de shell, un alias o un comando externo disponible con el mismo nombre.

En el caso donde no está por ejemplo una función de shell con el nombre cd, entonces builtin cdsería no llamar a ese. El uso builtin cdevita cualquier funcionalidad sobrecargada que el usuario haya agregado mediante una función de shell o un alias.

Ejemplo:

El cdcomando incorporado puede estar sobrecargado por una función que actualiza la solicitud:

cd() {
    builtin cd "$@" && PS1=$(__update_prompt)
}

donde __update_prompthay alguna otra función proporcionada por el usuario que genera una cadena.

El builtin cden la función no llamaría a la función recursivamente. El uso builtin cden un shell donde esta función está activa, adicionalmente, no llamaría a la función.


1 Hay Unices con un cdcomando externo (macOS y, creo, Solaris). El propósito de ese comando, que no puede cambiar el directorio de trabajo de un shell, es posiblemente satisfacer el estándar POSIX, que se enumera cdcomo una de las utilidades externas que deberían estar disponibles ( cdno es una de las "utilidades incorporadas especiales") . También puede servir como prueba para ver si sería posible cambiar el directorio de trabajo a un directorio dado .

Kusalananda
fuente
FWIW, MacOS también caería en la categoría de SO con un cdcomando externo .
yoann
@yoann De hecho lo hace.
Kusalananda
Gracias, me alegraste el día con una pedantería de primera categoría, bien investigada y con notas al pie.
James
la mayoría de los shells: es un programa externo para execlineb, pero luego su cd ejecutará sus argumentos restantes
Grump