Quelle est la différence entre les commandes cd et cd?

Réponses:

41

La cdcommande est intégrée, donc normalement builtin cdfera la même chose que cd. Mais il y a une différence s'il cdest redéfini en tant que fonction ou alias, auquel cas cdil appellera la fonction / alias mais builtin cdchangera toujours le répertoire (en d'autres termes, gardera le intégré accessible même s'il est encombré par une fonction.)

Par exemple:

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

Ou avec 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

L'utilisation builtinest également un bon moyen de définir une cdfonction qui fait quelque chose et change de répertoire (car l'appel à cdpartir de celle-ci ne ferait que rappeler la fonction dans une récursion sans fin.)

Par exemple:

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
la source
5
+1 Les exemples sont particulièrement illustratifs ici.
Tashus
2
Dans le cas d'un alias, y a-t-il une différence entre builtin cd mysubdiret \cd mysubdir?
gerrit
2
@gerrit Uniquement s'il existe une fonction nommée cd, auquel cas \cdelle contournerait l'alias et exécuterait la fonction. Voir stackoverflow.com/a/16506263/4518341
wjandrea
15

Dans la plupart des cas, il n'y a pas de différence (mais voir ci-dessous). La cdcommande est une commande intégrée dans tous les shells. Il doit être intégré 1 car une commande externe ne peut pas changer l'environnement du shell appelant, et changer le répertoire de travail constitue un changement dans son environnement.

La bashcommande builtinforce le shell à utiliser la version intégrée d'une commande, même si une fonction shell, un alias ou une commande externe peut être disponible avec le même nom.

Dans le cas où il est par exemple une fonction shell avec le nom cd, puis builtin cdne pas appeler. L'utilisation builtin cdcontourne toute fonctionnalité surchargée qui peut avoir été ajoutée via une fonction shell ou un alias par l'utilisateur.

Exemple:

La cdcommande intégrée peut être surchargée par une fonction qui met à jour l'invite:

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

__update_promptest une autre fonction fournie par l'utilisateur qui génère une chaîne.

Le builtin cddans la fonction n'appellerait pas la fonction récursivement. L'utilisation builtin cddans un shell où cette fonction est active, n'appellerait en outre pas la fonction.


1 Il existe des Unices avec une cdcommande externe (macOS et, je crois, Solaris). Le but de cette commande, qui ne peut pas changer le répertoire de travail d'un shell, est peut-être de satisfaire la norme POSIX, qui répertorie cdcomme l'un des utilitaires externes qui devraient être disponibles ( cdn'est pas l'un des "utilitaires intégrés spéciaux") . Il peut également servir de test pour voir si la modification du répertoire de travail en un répertoire donné serait possible .

Kusalananda
la source
FWIW, MacOS tomberait également dans la catégorie des OS avec une cdcommande externe .
yoann
@yoann En effet.
Kusalananda
Merci - vous avez fait ma journée avec une pédanterie de premier ordre, bien documentée et notée.
James
la plupart des shells - c'est un programme externe pour execlineb, mais son cd exécutera ensuite ses arguments restants
Grump