where is `cd` located?
What cd am I using?
If you're in Bash
cd is a builtin. The type command even bears this out:
$ type -a cd cd is a shell builtin cd is /usr/bin/cd cd is /bin/cd
The system will use the first thing in this list, so the builtin will be the preferred option, and the only one that works (see the section below on What is /bin/cd).
What's a builtin?
I like to think of builtins as functions that Bash knows how to do itself. Basically anything that you use a lot has been moved into the Bash "kernel" so that it doesn't have to go executing a process for each time.
You can always explicitly tell Bash that you want a builtin by using the
builtin command like so:
$ builtin cd
See the help about
$ help builtin
Why isn't cd in hash?
The hash is meant only to "hash" (aka. "save" in a key/value pair) the locations of files, not for builtins or keywords. The primary task for
hash is in saving on having to go through the
$PATH each time looking for frequently used executables.
These are typically the commands that are part of Bash's programming language features.
$ type while while is a shell keyword $ type for for is a shell keyword $ type ! ! is a shell keyword
Some things are implemented in multiple ways, such as
$ type -a [ [ is a shell builtin [ is /usr/bin/[ [ is /bin/[
cd as you've discovered.
What is /bin/cd?
On my Fedora 19 system
/bin/cd is actually a shell script:
$ more /bin/cd #!/bin/sh builtin cd "[email protected]"
But it doesn't do what you think. See these other U&L Q&A's for more details:
- What is the point of the `cd` external command?
- "Why can't I redirect a path name output from one command to "cd"?
POSIX's requires that it's there and in this implementation, it acts as a test, confirming that you're able to change directories to X, but then returning a return code confirming or denying that this is possible.
It is a builtin. See
man bash for the details of
cd and the Bash Manual for a description of builtins:
Builtin commands are contained within the shell itself. When the name of a builtin command is used as the first word of a simple command (see Simple Commands), the shell executes the command directly, without invoking another program. Builtin commands are necessary to implement functionality impossible or inconvenient to obtain with separate utilities.
whereis can show you that, e.g.
$ type grep grep is /bin/grep
$ whereis chown chown: /bin/chown /usr/share/man/man2/chown.2.gz /usr/share/man/man1/chown.1.gz
locate can also be useful for showing related files based on a wildcard search, e.g. for the chown command:
$ locate chown /bin/chown /home/durrantm/.rvm/gems/ruby-1.9.3-p194/doc/rubyzip-0.9.8/ri/Zip/ZipFileSystem/ZipFsFile/chown-i.ri /usr/lib/pt_chown /usr/share/man/man2/fchown32.2.gz /usr/share/man/man2/fchownat.2.gz /usr/share/man/man2/lchown.2.gz /usr/share/man/man2/lchown32.2.gz /usr/share/zsh/functions/Completion/Unix/_chown
Finally, when the result is that the command is 'builtin', as you saw for
cd it means that the code for it is actually in the bash main program and not a different program located elsewhere on disk.