How To Use The `man` Command
In our examination of the RBENV shim, we encountered the set
command. At that point, we hadn't yet encountered that command, and so we had to look it up in the docs.
In many cases, we can find the manual for various terminal commands using the man
command (short for "manual"). If we fail to find what we're looking for using man
, we can try checking StackOverflow or another source. But the quality of those sources can vary widely, so a useful habit is to stick to official docs when we can.
Also note that set
is a builtin command and therefore we have to access its docs via the help
command. Typically, we'd start our docs search with the man
command and switch to help
if we discover that the command in question is a builtin. A bit later in this post, we'll look at how to tell whether a command is a builtin command or not.
man
entries can be hard-to-parse if you've never encountered one before. Let's learn how to read them.
Looking up a man
page
One terminal command that most of us are familiar with by now is ls
, which prints out the contents of a directory. ls
is an internal command (i.e. not a builtin), so let's use it as a springboard to help us learn about man
pages.
If we type man ls
in the terminal, the result that we get starts out like this:
LS(1) General Commands Manual LS(1)
NAME
ls – list directory contents
SYNOPSIS
ls [-@ABCFGHILOPRSTUWabcdefghiklmnopqrstuvwxy1%,] [--color=when] [-D format] [file ...]
DESCRIPTION
For each operand that names a file of a type other than directory, ls displays its name as well as any requested, associated information. For each
operand that names a file of type directory, ls displays the names of files contained within that directory, as well as any requested, associated
information.
If no operands are given, the contents of the current directory are displayed. If more than one operand is given, non-directory operands are
displayed first; directory and non-directory operands are sorted separately and in lexicographical order.
The following options are available:
-@ Display extended attribute keys and sizes in long (-l) output.
...
Here we can see:
- the command's name and a brief description
- a synopsis of the command's usage (the order in which you'd type the command, its flags and arguments, etc.)
- a longer description of the command itself (here, "operand" means the argument you pass to
ls
) - a list of the command's possible arguments and flags, and what each one does
If we keep scrolling down, we'll also see:
- a list of environment variables which affect how
ls
works - a description of the exit code(s) that
ls
might return, and under what conditions they might be returned - examples of how to use the command
- various other bits of information which aren't immediately relevant to us
I recommend running man ls
in your terminal, and skimming the results in order to get familiar with the typical format of a man
page.
Searching a man
page for a string
You may have seen the command ls -la
in use by other devs, in a tutorial, etc. Let's assume you aren't yet familiar with the -la
flags (note that this syntax indicates we're passing two separate flags, and is equivalent to -l -a
). How can we get more information on these flags?
If we pull up the man
entry for ls
, we see it's quite long and includes documentation on many different flags. But that doesn't mean we have to read through these docs manually. We can search for a specific string, by using the /
character. If we type /-l
, we're taken to the first occurrence of the -l
string:
-@ Display extended attribute keys and sizes in long (-l) output.
If this occurrence doesn't look like what we want, we can type the n
key (i.e. lower-case "n") and move to the next occurrence:
-D format
When printing in the long (-l) format, use format to format the date and time output...
If we do this enough times, eventually we arrive at this entry:
-l (The lowercase letter “ell”.) List files in the long format, as described in the The Long Format subsection below.
If you accidentally skip past the occurrence you want, you can type N
(capital "n") to go back one entry.
There are many more commands that you can use when searching a man
page for a string, as well as many more commands to use in general. To see an exhaustive list, type h
while inside a man
page.
Builtin vs. External Commands
Depending on the command you give it, sometimes man
will give you documentation on that command (like it did with ls
). Other times, it returns an explanation of what a builtin command is in UNIX.
For example, let's try looking up the set
command in its man
page. I type man set
into my terminal and I see the following:
BUILTIN(1) General Commands Manual BUILTIN(1)
NAME
builtin, !, %, ., :, @, [, {, }, alias, alloc, bg, bind, bindkey, break, breaksw, builtins, case, cd, chdir, command, complete, continue, default,
dirs, do, done, echo, echotc, elif, else, end, endif, endsw, esac, eval, exec, exit, export, false, fc, fg, filetest, fi, for, foreach, getopts,
glob, goto, hash, hashstat, history, hup, if, jobid, jobs, kill, limit, local, log, login, logout, ls-F, nice, nohup, notify, onintr, popd, printenv,
printf, pushd, pwd, read, readonly, rehash, repeat, return, sched, set, setenv, settc, setty, setvar, shift, source, stop, suspend, switch, telltc,
test, then, time, times, trap, true, type, ulimit, umask, unalias, uncomplete, unhash, unlimit, unset, unsetenv, until, wait, where, which, while –
shell built-in commands
SYNOPSIS
See the built-in command description in the appropriate shell manual page.
DESCRIPTION
Shell builtin commands are commands that can be executed within the running shell's process. Note that, in the case of csh(1) builtin commands, the
command is executed in a subshell if it occurs as any component of a pipeline except the last.
If a command specified to the shell contains a slash ‘/’, the shell will not execute a builtin command, even if the last component of the specified
command matches the name of a builtin command. Thus, while specifying “echo” causes a builtin command to be executed under shells that support the
echo builtin command, specifying “/bin/echo” or “./echo” does not.
...
This man
page looks a bit different. It doesn't mention the command name (set
) in the top-left corner, the way the man ls
results did. Instead we just see the word BUILTIN
.
So when does it give you one result, vs. the other?
As it turns out, man
pages are provided only for "external commands", i.e. commands which come from UNIX. But the shell is not UNIX. UNIX is the operating system, and the shell is the application we're using to interact with the operating system. In fact, the reason why it's called the "shell" is that it surrounds the operating system, like an eggshell.
The set
command is a builtin program provided by the shell, not an external command provided by UNIX. It's for this reason that shell authors keep the docs for their commands separate from the docs for external commands. The filesystem can be a messy place, and it's important to maintain strict compartmentalization for the sake of keeping things organized. As the British say, "everything in its right place".
How to tell if a command is a builtin
A quick an easy way to tell whether a command is a builtin command, external command, or something else is by using the type
command. If we run type set
in Zsh, we see:
$ type set
set is a shell builtin
$
And if we type type ls
, we see:
$ type ls
ls is /bin/ls
$
Lastly, let's define a shell function named foo
, and run type foo
:
$ foo() {
function> echo 'Hello world'
function> }
$ type foo
foo is a shell function
$
Based on the response from type (command)
, we can tell ahead of time whether we should look up the command's docs using man
or help
.