cd
não é um comando externo - é uma função interna do shell. Ele é executado no contexto do shell atual e não, como fazem os comandos externos, em um contexto fork / exec'd como um processo separado.
Seu terceiro exemplo funciona, porque o shell expande a variável e a substituição de comando antes de chamar o cd
builtin, de modo que cd
receba o valor de ${HOME}
como seu argumento.
Sistemas POSIX do tem um binário cd
- na minha máquina FreeBSD, está em /usr/bin/cd
, mas não faz o que você pensa. Chamar o binário cd
faz com que o shell bifurque / exec o binário, o que realmente altera seu diretório de trabalho para o nome que você passa. No entanto, assim que isso acontecer, o binário é encerrado e o processo forked / exec'd desaparece, retornando ao seu shell, que ainda está no diretório em que estava antes de iniciar.