I want to look into the source code behind the command cd, but cd doesn't seem to have its own package so which package is it in?
- 193,181
- 53
- 473
- 722
-
1DOS/Windows has the notion of internal commands..old MS DOS doesn't contained a cd.exe or cd.com it was built into command.com(aka DOS Shell)...i think in Linux it might be somewhat similar...old MS DOS borrowed a lot of ideas from *IX...so may be that is built in the shell or very basic component which is always loaded. In MS DOS there used to be external commands like dircopy etc...(i am not sure whether it indeed is external command in MS DOS) External commands are bundled out of command.com – Ashu Mar 11 '16 at 14:52
-
6Related: [Why doesn't `sudo cd /var/named` work?](http://askubuntu.com/q/291666/11751) – user Mar 11 '16 at 16:00
-
Protip: Don't uninstall `cd` – PyRulez Mar 11 '16 at 18:02
-
3@kos: or "whatever your current shell is" I guess :) (I doubt any useful shell exists that doesn't let you change directories...) – UncleZeiv Mar 11 '16 at 18:25
-
@UncleZeiv Indeed, professional bias leads to always assume Bash. :) – kos Mar 11 '16 at 18:32
-
@Rinzwind Posted the comment at the same time you edited, forgot to remove it later etc. Removed :) – kos Mar 11 '16 at 19:02
-
1Related SO question: https://stackoverflow.com/questions/881560/source-code-for-unix-environments-cd-command – therefromhere Mar 12 '16 at 02:05
-
2Related, perhaps a dupe: [Why wouldn't the `which` command work for `cd`? I can't find the executable for `cd` either!](http://askubuntu.com/q/532788/158442) – muru Mar 12 '16 at 02:44
-
1@Ashu in Unix it's called *builtin commands* – phuclv Mar 12 '16 at 03:46
-
@UncleZeiv: I believe `rbash` prohibits changing directories. – Kevin Mar 12 '16 at 07:43
-
@PyRulez how could you _ever_ do this for a builtin command? – Ruslan Mar 12 '16 at 15:45
-
Surprisingly, it [is not always just a built-in](http://unix.stackexchange.com/q/50058). – kojiro Mar 13 '16 at 12:54
-
5Possible duplicate of [Why wouldn't the \`which\` command work for \`cd\`? I can't find the executable for \`cd\` either!](https://askubuntu.com/questions/532788/why-wouldnt-the-which-command-work-for-cd-i-cant-find-the-executable-for) (Also related: [Where are commands `fg`, `bg` and `jobs` installed?](https://askubuntu.com/questions/613470/where-are-commands-fg-bg-and-jobs-installed)) – Eliah Kagan Jun 26 '19 at 16:19
5 Answers
Find out what type a command is using the type command.
$ type cd
cd is a shell builtin
$ type ls
ls is aliased to `ls --color=auto'
$ type cat
cat is /bin/cat
You can see, cd is a shell builtin.
This means, it's a part of your shell which is by default Bash. That's of course also the software package it's contained in.
For installed commands that are not shell builtins but executable files, use dpkg -S to find out the package:
$ dpkg -S $(which cat)
coreutils: /bin/cat
To get help for built in commands, use the help command (which is also built in):
$ help cd
cd: cd [-L|[-P [-e]] [-@]] [dir]
Change the shell working directory.
[... output shortened ...]
- 105,631
- 46
- 284
- 425
-
5`dpkg -S` only applies to package installed software - if they installed from a tarball or a bin file it won't help them there - but `type` will still identify it as a different binary and not a built in or an alias – Thomas Ward Mar 11 '16 at 15:26
-
4Ok true but I hope we assume a vanilla Ubuntu when answering about default applications. And Ubuntu without bash installed seems unlikely ;-) – Rinzwind Mar 11 '16 at 15:41
-
1You can use apt-file search
instead of dpkg -S for searching for files in packages, that are not installed. – ortang Mar 11 '16 at 16:04 -
@ortang `apt-file` is not default installed nor fully updated last I checked - this is one way yes but not a default way – Thomas Ward Mar 11 '16 at 18:25
-
4I recommend `type -a cd` to show `a`ll locations of this command. There still should only be the shell builtin. Compare, for example, with `type -a printf` which comes in both builtin and /usr/bin varieties. – Digital Trauma Mar 11 '16 at 19:25
-
2@DigitalTrauma: Very good comment! Indeed, there are two sorts of builtins: ones which *must* be builtins because they *cannot* possibly work as external commands (e.g. `cd`, `set`, which alter the calling process's environment) and "convenience" builtins which are builtins for performance reasons (avoiding the overhead of a subshell) or because you would like to have them available even on a system with a completely hosed `$PATH` or something like that (e.g. `[`, `echo`, `printf`). The latter can sometimes lead to confusion because e.g. `man echo` will show the command's manpage, but … – Jörg W Mittag Mar 12 '16 at 01:25
-
… `echo foo` will execute the builtin, which may have different features or accept different flags, options and arguments, or have differing behavior in some other ways. This can happen for example when using Zsh, but with the manpages provided by GNU tools, or on OSX, where the default shell is GNU Bash, but the commands are mostly BSD. – Jörg W Mittag Mar 12 '16 at 01:27
-
The source code for "cd" can be found from the git browser http://git.savannah.gnu.org/cgit/bash.git/tree/builtins/cd.def?id=bash-4.3 – James K Mar 12 '16 at 20:24
cd is necessarily a shell built-in. If the shell spawned a child process that changed the working directory and then exited, the parent process (the shell itself) would not be affected.
As to the source code of cd, all it needs to do is call chdir(2), which changes the working directory of the process. See chdir at opengroup.org which states:
The chdir() function shall cause the directory named by the pathname pointed to by the path argument to become the current working directory; that is, the starting point for path searches for pathnames not beginning with '/'.
- 401
- 3
- 7
-
3Indeed. Compare [Why doesn't `sudo cd /var/named` work?](http://askubuntu.com/q/291666/11751). – user Mar 11 '16 at 16:00
-
3Right. I only added an answer because the other answers didn't address why `cd` must be a built-in. What is more misleading is that sometimes there actually is a `/usr/bin/cd`. – Tim B Mar 11 '16 at 16:03
Here is a man page for cd but it not an official one since cd is part of the "Shell Builtin Commands". Just like some other commands ...
alias, bg, bind, break, builtin, command, compgen, complete,
continue, declare, dirs, disown, echo, enable, eval, exec, exit,
export, fc, fg, getopts, hash, help, history, jobs, kill, let, local,
logout, popd, printf, pushd, pwd, read, readonly, return, set, shift,
shopt, source, suspend, test, times, trap, type, typeset, ulimit,
umask, unalias, unset, wait
See the man page for bash. From the link cd states:
cd [-L|-P] [dir]
Change the current directory to dir. The variable HOME is the default dir. The variable CDPATH defines the search path for the directory containing dir. Alternative directory names in CDPATH are separated by a colon (:). A null directory name in CDPATH is the same as the current directory, i.e., ''.''. If dir begins with a slash (/), then CDPATH is not used. The -P option says to use the physical directory structure instead of following symbolic links (see also the -P option to the set builtin command); the -L option forces symbolic links to be followed. An argument of - is equivalent to $OLDPWD. If a non-empty directory name from CDPATH is used, or if - is the first argument, and the directory change is successful, the absolute pathname of the new working directory is written to the standard output. The return value is true if the directory was successfully changed; false otherwise.
Which package is the command 'cd' in?
That would be bash
-
5Adding to this, while many of the builtin tools *could* be external commands, there is no way that the `cd` command could be implemented as an external command, since it's impossible for a subprocess to change the working directory of its parent process. – Martin Tournoij Mar 11 '16 at 18:35
-
+1 for the link to the package, from which link the source code can be readily obtained. – Mathieu K. Mar 12 '16 at 09:56
The actual source code of cd is for
- Bash in
builtins/cd.defat the end of the file - TCSH in
sh.dir.cas the functiondochngd - PDKSH (Public Domain Korn shell found in some BSDs) in
c_ksh.cright at the top of the file - Korn 93 (Original Korn shell, old version) in
src/cmd/ksh93/bltins/cd_pwd.c
The sys-call chdir for
- Linux kernel is in
fs/open.c - FreeBSD is where the link at the beginning of this item points to
- other BSD-type OSs and OpenSolaris work quite similar
It might be of note that the sys-calls are still not the end of the chain, that would be down at the individual file system level.
- 90,425
- 20
- 200
- 267
- 223
- 1
- 4
Right, so as everyone has written, cd is built into whatever shell you use, because a process cannot affect the working directory of its parent. cd has a few bells and whistles tacked on (I mean pushd and friends, cd without an argument, etc.), but if you take the trouble to dig through the source you'll be underwhelmed: the main thing is that cd calls the chdir(2) system call.
There's not much to see because unlike, say, an environment variable like HOME, the "working directory" is a system primitive: It's one of the attributes that every process has, like (real) user id or scheduling priority. It is the starting point when opening files with relative paths.
- 1,028
- 7
- 9