Qual é a diferença entre os comandos embutidos cd e cd?

Respostas:

41

O cdcomando é um built-in, então normalmente builtin cdfará o mesmo que cd. Mas há uma diferença se cdfor redefinido como uma função ou um alias; nesse caso cd, chamará a função / alias, mas builtin cdainda mudará o diretório (em outras palavras, manterá o built-in acessível, mesmo se for derrotado por uma função).

Por exemplo:

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 com um 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

Usar builtintambém é uma boa maneira de definir uma cdfunção que faz algo e altera o diretório (uma vez que a chamada a cdpartir dele continuaria chamando a função novamente em uma recursão sem fim).

Por exemplo:

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
fonte
5
+1 Os exemplos são particularmente ilustrativos aqui.
Tashus 19/01
2
No caso de um alias, existe alguma diferença entre builtin cd mysubdire \cd mysubdir?
gerrit 19/01
2
@gerrit Somente se houver uma função nomeada cd, caso em \cdque ignoraria o alias e executaria a função. Veja stackoverflow.com/a/16506263/4518341
wjandrea
15

Na maioria dos casos, não há diferença (mas veja abaixo). O cdcomando é um comando interno em todos os shells. Ele precisa ser incorporado 1, pois um comando externo não pode alterar o ambiente do shell de chamada e a alteração do diretório de trabalho constitui uma alteração em seu ambiente.

O bashcomando builtinforça o shell a usar a versão interna de um comando, mesmo que possa haver uma função de shell, alias ou comando externo disponível com o mesmo nome.

No caso em que não é , por exemplo, uma função de shell com o nome cd, então builtin cdseria não chamar isso. O uso de builtin cdignora qualquer funcionalidade sobrecarregada que possa ter sido adicionada por meio de uma função de shell ou alias pelo usuário.

Exemplo:

O cdcomando interno pode estar sobrecarregado por uma função que atualiza o prompt:

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

Onde __update_prompt está outra função fornecida pelo usuário que gera uma string.

A builtin cdfunção in não chamaria a função recursivamente. O uso builtin cdem um shell em que essa função está ativa também não chamaria a função.


1 Existem Unices com um cdcomando externo (macOS e, acredito, Solaris). O objetivo desse comando, que não pode alterar o diretório de trabalho de um shell, é possivelmente satisfazer o padrão POSIX, que é listado cdcomo um dos utilitários externos que devem estar disponíveis ( cdnão é um dos "utilitários embutidos especiais") . Também pode servir como um teste para verificar se seria possível alterar o diretório de trabalho para um determinado diretório .

Kusalananda
fonte
FWIW, o MacOS também cairia na categoria de sistemas operacionais com um cdcomando externo .
yoann 19/01
@yoann De fato, sim.
Kusalananda
Obrigado - você fez o meu dia com alto nível, bem pesquisado, pedantismo com notas de rodapé.
james
a maioria dos shells - é um programa externo para o execlineb, mas o cd executará seus argumentos restantes
Grump