88

As referenced in this fine answer, POSIX systems have an external binary cd in addition to the shell builtin. On OS X 10.8 it's /usr/bin/cd. You can't use it like the builtin cd since it exits immediately after changing its own working directory. What purpose does it serve?

4
  • Note that Ubuntu and CentOS (and therefore presumably Red Hat) don't have /usr/bin/cd, only the shell built-in. Commented Oct 5, 2012 at 21:03
  • 1
    My Fedora 19 includes /bin/cd however.
    – slm
    Commented Feb 26, 2014 at 14:38
  • 1
    Debian (I checked several releases, including current testing) has neither /bin/cd nor /usr/bin/cd.
    – derobert
    Commented Feb 26, 2014 at 17:16
  • 1
    I guess that makes these systems not strictly POSIX. Just like everyone else. :)
    – kojiro
    Commented Apr 19, 2014 at 15:39

3 Answers 3

84

It serves primarily as making sure the POSIX tool-chest is available both inside and outside a shell (see the POSIX rationale for requiring those).

For cd, that is not tremendously useful but note that cd changes directories but has other side effects: it returns an exit status that helps determine whether you're able to chdir() to that directory or not, and outputs a useful error message explaining why you can't chdir() when you can't.

Example:

dirs_i_am_able_to_cd_into=$(find . -type d -exec cd {} \; -print)

Another potential side-effect is the automounting of a directory.

On a few systems, most of the external commands for the standard shell builtins are implemented as a symlink to the same script that does:

#! /bin/sh -
"${0##*/}" "$@"

That is start a shell and run the builtin in it.

Some other systems (like GNU), have utilities as true executable commands which can lead to confusions when the behavior differs from the shell builtin version.

5
  • 6
    +1 for the observation about side effects and error messages. It is not always well explained to new users that a lot of clever idioms in Unix come from careful use of side effects. And the man pages themselves have never been good at describing the bigger picture.
    – RBerteig
    Commented Feb 11, 2014 at 1:11
  • 1
    Came here from a similar question on SO, could you elaborate what you mean when you say "automounting of a directory" ?
    – ffledgling
    Commented Jun 29, 2016 at 14:47
  • 2
    @ffledgling, see en.wikipedia.org/wiki/Automounter Commented Jun 29, 2016 at 16:35
  • 3
    To unpack Stéphane Chazelas's thought a little: if you need to ensure that an automoutable directory is in fact mounted without making any changes on it and without making an attempt to read any files, you could use the external cd command. Might be useful in monitoring the availability of an automountable remote filesystem, or perhaps before doing something time-critical with one.
    – telcoM
    Commented Jun 5, 2018 at 13:30
  • "without making any changes on it" - It may update its access time if that option is enabled in the filesystem. Commented Jun 29, 2022 at 17:12
14

The fact a non builtin cd command is available is essentially due to the POSIX requirement for all regular builtins to be callable by the exec family commands env, find, nice, nohup, time and xargs combined to the fact some of these commands are not being themselves implemented as builtins.

That doesn't make much sense for cd though as combining it with these commands is quite pointless. Here are more or less tenable examples though:

find . -type d -exec cd {} \;
env HOME=/foo cd
2
  • 4
    A number of built-ins are actually exempt from that rule. Bizarrely, cd is not one of them.
    – Kevin
    Commented Mar 12, 2016 at 7:46
  • 5
    @Kevin I wrote it is a requirement for all regular builtins, the exempted ones are special builtins: break, :, continue, . , eval, exec, exit, export, readonly, return, set, shift, times, trap, unset would be irrelevant as external commands while cd is a regular builtin that has some documented use cases as a command.
    – jlliagre
    Commented Mar 12, 2016 at 11:02
3

In addition to checking whether a path corresponds to an accessible directory, the cd executable will process and use the CDPATH variable, and will print out the absolute path of the resolved directory if it was used successfully.

$ export CDPATH=/usr
$ echo bin lib | xargs -n 1 cd
/usr/bin
/usr/lib

This is only very occasionally useful, but would save reimplementing the same logic for searching for matching directories. A concrete use case is finding the first existing directory of a particular name under several possible parents.

cd also processes OLDPWD for cd -, but that is less concretely useful since the environment variable would already be available.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .