6

Possible Duplicate:
Why is cd not a program?

I noticed that every other commonly used util, like ls, cp, rm, etc. are actually files in /bin -- but cd is not. Nor is it in any other binaries dir (e.g. /usr/bin, /bin, /sbin etc.).

Why is that the case?

amphibient
  • 12,472
  • 18
  • 64
  • 88

2 Answers2

7

cd is a shell builtin. So it's part of the shell itself, not a separate executable.

There are basically two classes of builtin.

  • Special builtins are closely tied to the shell, and either can't be implemented independently, or aren't, because to do so wouldn't make functional sense (they are mostly to do with shell control). They are called 'special' because they have specific error handling and variable assignment semantics.
  • Regular builtins are normally implemented in the shell for performance reasons, because they manipulate shell internals (e.g. cd) or because they are technically easier that way. In some cases, a regular builtin may also exist in non-builtin form. An example of the latter case is echo, which is implemented in every modern shell, but also exists, mainly for historical reasons, as /bin/echo.

An additional reason for making critical functions builtin is that it ensures core functionality continues to remain accessible, even if something catastrophic happens to your system. For example, this could be important if shared libraries become corrupted or inaccessible, if you lost access to /bin or /sbin, or if the system becomes resource-limited in a way that disallows running further executables.

  • very good, thanks. but why is it that cd is a builtin and similar commands like ls or cp are executables ? – amphibient Dec 22 '12 at 05:21
  • 4
    cd doesn't actually do anything. cp copies a file from here to there, and find searches the filesystem. cd just changes what directory you are "in", which is just a notional idea for navigating in the shell. – Andy Lester Dec 22 '12 at 05:32
  • @foampile - I've added some further explanation. – ire_and_curses Dec 22 '12 at 05:49
  • 1
    @AndyLester Changing directory doesn't count as "doing anything"? Not sure that's entirely accurate... – Chris Down Dec 22 '12 at 08:59
  • Your statement In some cases, a regular builtin may also exist in non-builtin form should really be, by the POSIX standard, All regular builtins must also exist as a non builtin form, i.e. an external command so this is not for historical reasons but for technical and compliance ones that they exist as such. – jlliagre May 23 '16 at 21:54
3

Some Unix history resources say that cd was external command at a some (quite early) period of Unix development. This was a special command which was able to modify parent's current directory.

You can see rudiments of this historical state in the fact that Solaris has /usr/bin/cd as a real command, in addition to shell builtins. But I'm unsure it does anything real in the current systems.

This being as external command was a temporary solution which was exterminated as soon as Unix developers became able to have shell builtins. It's too expensive to have a whole command (which shall have own process, be loaded from disk, etc.) in the place where simple system call is enough. So it became a builtin and, since this, didn't changed its state ever.

One could create a shell where nearly any command becomes built in; this is only a kind of design trade-off. For instance, cp mentioned here could be good candidate for this; and such building-in had been implemented in some shells for MS-DOS. But, in Unix, process creation and start is cheaper, and there is no need to invent a functionally internally unless it couldn't be implemented from another process. This includes cd, ulimit, exit, variable manipulations, control flow commands (if, for, while, etc.) and so forth.

Netch
  • 2,529
  • 2
    There was no 'parent' in the period of unix history you are thinking of - the shell was replaced with the file you executed, and at the end it executed a new shell. – Random832 Dec 22 '12 at 13:21
  • Not only Solaris but all Unix systems must have a non builtin cd command. This is not for historical reasons but to comply with the POSIX standard. GNU/Linux is one of the rare Unix like systems that doesn't implement it, but it doesn't claim to be Unix compliant either. – jlliagre May 21 '16 at 14:47
  • @jlliagre No, POSIX literally says: "Since cd affects the current shell execution environment, it is always provided as a shell regular built-in." I've checked 2008 revision. Don't know what version you use, but please check it for obsoleteness. – Netch May 23 '16 at 04:12
  • 1
    You are missing my point. For the reason you quote cd is indeed always provided as a shell builtin but what the standard is also requiring is for cd to be available as a regular command too. See the last paragraph of http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap01.html#tag_17_06 S – jlliagre May 23 '16 at 07:36
  • I'm afraid there are other slightly incorrect statements in your reply. The original cd command was not really modifying its parent process environment because the parent/child relationship wasn't yet invented. It is not the implementation of builtins or the external command expensiveness that obsoleted cd but the fact cd ceased to work after the fork system call introduction that forced the shell developers to implement it as a builtin. There was no sensible alternative. – jlliagre May 23 '16 at 21:43