33

When I use the type command to find out if cat is a shell built-in or an external program I get the output below:

-$ type cat
cat is hashed (/bin/cat)
-$

Does this mean that cat is an external program which is /bin/cat?

I got confused, because when I checked the output below for echo I got to see that it is a built-in but also a program /bin/echo

-$ type echo
echo is a shell builtin
-$ which echo
/bin/echo
-$ 

So I could not use the logic that /bin/cat necessarily means an external program, because echo was /bin/echo but still a built-in.

So how do I know what cat is? Built-in or external?

psmears
  • 461
  • 3
  • 8
sps
  • 1,396
  • 5
  • 15
  • 23
  • 1
    -The command cat is an external program that makes part of the system, per cause the many actions that it can perform is not a simple built-in. – Joke Sr. OK Jun 10 '15 at 03:30
  • 12
    `type which` could give you the answer why `which` won't give you the answer. – Dubu Jun 10 '15 at 13:46
  • 1
    Depends on the shell you are using – nsn Jun 10 '15 at 17:28
  • 6
    Fun fact: both `cat` and `ls` are/were written by Stallman himself. You'd be surprised how much stuff he wrote. Don't forget he wrote the first versions of the compiler that is today the best compiler in the world that compiles EVERYTHING and most of the core utils. Just sayin' – Alec Teal Jun 11 '15 at 14:12
  • 2
    @AlecTeal You do realize that most Unix systems use versions of ls and cat that long predate the GNU versions that Richard Stallman had a hand in? – Ross Ridge Jun 11 '15 at 16:06
  • @RossRidge confirmed on Debian, if you get the source you'll notice the author is specified at the top of most files. That's my source, personal experience. So I stand by my coment – Alec Teal Jun 11 '15 at 16:56
  • @AlecTeal So you really do think Richard Stallman wrote the first version of cat and ls? – Ross Ridge Jun 11 '15 at 17:14
  • 1
    @RossRidge not the first, nor the last. But wrote ones that are in use right now with every Debian (default) installation. For example I would imagine Solaros has its own – Alec Teal Jun 11 '15 at 18:05
  • @nsn: Do you actually know of any shells for which `cat` is a builtin? I don't. – Nate Eldredge Jun 12 '15 at 05:00
  • 1
    @AlecTeal FreeBSD uses its own `cat` and `ls`, for one. Most non-GNU/Linux systems would be the same. – felixphew Jun 12 '15 at 06:49
  • 1
    on `sash` the `cat` is a builtin. – Basile Starynkevitch Jun 12 '15 at 07:26
  • 1
    Another example would be ash + busybox. Not exactly embedded in the shell but busybox is a monolythic piece of software providing a very large set of shell commands (cat, ls, cp...) often used with ash. – nsn Jun 12 '15 at 08:43
  • @NateEldredge Some versions of MKS shell have `cat` and `ls` as actual shell builtins. I think with busybox they show up as external commands even though they're all links to the same executable. – Ross Ridge Jun 13 '15 at 05:13

6 Answers6

60

type tells you what the shell would use. For example:

$ type echo
echo is a shell builtin
$ type /bin/echo
/bin/echo is /bin/echo

That means that if, at the bash prompt, you type echo, you will get the built-in. If you specify the path, as in /bin/echo, you will get the external command.

which, by contrast is an external program that has no special knowledge of what the shell will do. On debian-like systems, which is a shell script which searches the PATH for the executable. Thus, it will give you the name of the external executable even if the shell would use a built-in.

If a command is only available as a built-in, which will return nothing:

$ type help
help is a shell builtin
$ which help
$ 

Now, let;s look at cat:

$ type cat
cat is hashed (/bin/cat)
$ which cat
/bin/cat

cat is an external executable, not a shell builtin.

John1024
  • 73,527
  • 11
  • 167
  • 163
  • 5
    You could `type -all echo` to find out (in order) which are the different "echo" known to the shell (the first one being the one the shell will call, if you don't specify something to change the order, like invoking `"echo"` or `\echo`, or `command echo` ) – Olivier Dulac Jun 10 '15 at 09:28
  • Good answer. One addition: There are two versions of `echo` for historical reasons. It started out as an external command, then was added as a built-in. Early versions of the Bourne shell (`/bin/sh`) did not have it. `/bin/echo` was kept on for compatibility, since all sorts of things depended on it. (The same thing happened with `test`.) – alexis Jun 11 '15 at 11:26
  • 1
    Side note: `which` itself can be a shell built-in cmd, for example in tcsh: `which which` `which: shell built-in command.` – Dan Cornilescu Jun 11 '15 at 16:47
  • I'm arriving late to the party, but why don't you check its man page and you can actually see the number between parenthesis, which indicates if it is a shell built-in or whatever – poz2k4444 Jun 16 '15 at 20:34
46

cat is hashed (/bin/cat) is just like cat is /bin/cat (that is, it's an external program).

The difference is that you already ran cat in this session, so bash has already looked it up in $PATH and stored the resulting location in a hash table so it doesn't have to look it up again in this session.

To see all the commands that have been hashed in your session, run hash

$ hash
hits    command
   2    /usr/bin/sleep
   3    /usr/bin/man

$ type sleep
sleep is hashed (/usr/bin/sleep)

$ type man
man is hashed (/usr/bin/man)

$ type ls
ls is /usr/bin/ls

$ type cat
cat is /usr/bin/cat

$ type echo
echo is a shell builtin
André Chalella
  • 553
  • 3
  • 8
4

You can also use the command whereis that is more efficient because it shows where the command is on the machine like also the manual pages library, etc..

Anthon
  • 78,313
  • 42
  • 165
  • 222
Joke Sr. OK
  • 903
  • 1
  • 8
  • 11
4

Another way to check list of shell builtin : Using compgen which is shell builtin itself!

Following command lists all shell builtin commands:

compgen -b

You can check for cat, echo by greping like:-

$ compgen -b | grep echo
echo
$ compgen -b | grep cat
$ 

You can see compgen -b | grep cat returns with no output, means cat is not shell builtin.

Visit a list of useful options provided by compgen.


You can also use one another builtin command : help to display shell-builtin.

$ help help
help: help [-dms] [pattern ...]
    Display information about builtin commands.
Pandya
  • 23,898
  • 29
  • 92
  • 144
  • I can't find any formal documentation for these options, do you know where it exists? – Random832 Jun 10 '15 at 14:21
  • @Random832 are you talking about options for `compgen`? – Pandya Jun 11 '15 at 03:40
  • yeah, I couldn't find anything in the Bash manpage about what -b or half the other options mean. Found it later at http://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html – Random832 Jun 11 '15 at 03:42
  • @Random832 try `man bash | grep -e '-A action$' -A 32` you probably get output like [this](http://pastebin.com/kfgbweGw). (increase/decrease digit after `-A` to manage properly). – Pandya Jun 11 '15 at 04:03
2

Others have already answered about cat, I would just like to explain the issue with echo. If you use type's -a option (list all matches), you will see that echo is both a shell builtin and an external program:

$ type -a echo
echo is a shell builtin
echo is /bin/echo

The two are completely independent of one another. type with no options will simply return the first matching command found. So, type foo will show you what will be executed if you run foo. There may be other options, but those won't be shown unless you use -a.

terdon
  • 234,489
  • 66
  • 447
  • 667
2

Since there are several good answers here about using type to find out if a command such as cat is a builtin or an external program. I am going to take a more general approach. There are some commands that must be builtins because they affect the current shell. Three classic examples are cd, exec, and exit. There are some commands that must not be builtins because their functionality depends on the behavior of the execve or system calls. Examples of such programs include su, sudo, calife and super. All other commands can be built as builtins or external programs. cat is a great example program of this class as there are shells that include it as a builtin and shells that do not. It is worth noting that many commands of this class that are available as builtins are also available as external programs.

roaima
  • 107,089
  • 14
  • 139
  • 261
hildred
  • 5,759
  • 3
  • 30
  • 43