In this chapter, I help you find your way around your Mac from the command line and, at the same time, teach you some of the most common navigational commands and conventions.
For right now, you’re going to look, but not touch—that is, nothing you do here can change any files or cause any damage, as long as you follow my instructions.
Discover Where You Are
Ready to start learning some commands? Here we go. Open a Terminal window and enter this:
pwd command stands for “print working directory,” and it gives you the complete path to the directory you’re currently using. If you haven’t done anything else since opening a Terminal window, that’s your home directory, so you’ll see something like this:
That’s not exciting, but it’s extremely important. As you navigate through the directory structure, it’s easy to get lost, and ordinarily your prompt only tells you the name of your current directory, not where it’s located on your disk. When you’re in a deeply embedded directory, being able to tell exactly where you are can be a huge help.
See What’s Here
If you were in the Finder, you’d know exactly what’s in the current folder just by looking. Not so on the command line; you must ask explicitly. To get a list, you use the “list” command:
What you get by default is a list along the lines of the following:
Desktop Downloads Movies Pictures Documents Library Music Public
Items are listed alphabetically, top to bottom and then left to right. But as you can see, this doesn’t tell you whether these items are files or directories, how large they are, or anything else about them. So most people prefer the more-helpful long format by adding the
This produces a result something like:
drwx------@ 18 jk staff 612 Feb 12 09:42 Desktop drwx------@ 108 jk staff 3672 Feb 9 14:35 Documents drwx------@ 15 jk staff 510 Feb 12 11:17 Downloads drwx------+ 94 jk staff 3196 Feb 11 22:40 Library drwx------@ 13 jk staff 442 Dec 30 15:34 Movies drwx------@ 15 jk staff 510 Aug 27 15:02 Music drwx------+ 14 jk staff 476 Jan 26 19:40 Pictures drwxr-xr-x+ 7 jk staff 238 Jan 22 23:13 Public
Reading from right to left, notice that each line ends with the item’s name. To the left of the name is a date and time showing when that item was most recently modified. To the left of the date is another number showing the item’s size in bytes. See the sidebar on the next page, Making Output (More) Human-Readable, to find out how to turn that number into a nicer format. (In the case of a directory, the number shown by
ls -l doesn’t tell you the total size of the directory’s contents, only the size of the information stored about the directory. The “disk usage” command can get a directory’s size, enter
du -sh directory-name.)
Later in this book, in Understand Permission Basics, I go into more detail about all those characters that occupy the first half of each line, such as
drwxr-xr-x + 7 jk staff; those characters describe the item’s permissions, owner, and group. For the moment, just notice the very first letter—it’s
d in every item of this list. The
d stands for “directory,” meaning these are all directories. If the item were a file, the
d would be replaced with a hyphen (
-), for example:
Finally, look at one other number, between the permissions and owner (in
drwx------ 14 jk the number is 14). That’s the number of links to the item, and although links are too advanced to explain in detail here, the number serves one practical purpose: it gives you an approximation of the number of items in a directory. In fact, it is always at least two higher than the number of visible files or directories in the directory (for complicated reasons). For now, just know that the number can tell you, at a glance, if a directory has only a few items or many.
However, as I hinted in The Startup Volume is Read-Only, starting in Catalina, the
ls command doesn’t always tell the entire story. For example, if you enter
ls /Applications you’ll see only the third-party applications (which are really stored in
Macintosh HD - Data/Applications). What if you want to see the apps built into macOS—the ones that are stored in
Macintosh HD/Applications? In that case, you have to enter
ls /System/Applications. (The same goes for
/Library and other top-level directories.) You can’t use the
ls command to show you the merged contents of these folders as the Finder does.
I don’t want to belabor the
ls command, but it will without question be one of the top two or three things you type on the command line—you’ll use it constantly. So it pays to start getting
ls (along with a flag or two) into your muscle memory. For a way to display even more information with
ls, see the recipe List More Directory Information.
Repeat a Command
If you’ve just entered a two-character command, it’s no big deal to enter it again. But sometimes commands are quite complex, wrapping over several lines, and retyping all that is a pain. So I want to tell you about two ways of repeating commands you’ve previously entered.
First, you can use the ↑ and ↓ keys to move backward and forward through the list of commands you’ve recently typed. For example, if the last command you typed was
ls -lh, simply pressing ↑ once puts that on the command line. (Then, to execute it, you would press Return or Enter.) Keep pressing ↑, and you’ll step backward through even more commands. You can even scroll through commands you entered in previous sessions. The ↓ key works the same way—it progresses forward in time from your current location in the list of previous commands.
The !! Command
Another handy way of repeating a command is to enter
!! (that’s right: just two exclamation points). This repeats your previous command. Try it now. Enter, say,
pwd, and get the path of your current directory. Then enter
!! and you’ll get the same output.
Again, this isn’t terribly interesting when you’re talking about short commands, but it can save time and effort with long commands.
Cancel a Command
What if you type some stuff on the command line and realize you don’t want to enter the command? Well, you could backspace over it, but that may take a while if there’s a lot of text on the line.
An easier way to back out of a command without executing it is to press either Control-C or ⌘-. (period). The shell creates a new, blank command line, leaving your partially typed line visible but unused. (Your command history won’t include canceled commands.)
Move into Another Directory
This has been a lovely visit in your home directory, but now it’s time to explore. To change directories, you use the
cd command. As you saw a moment ago, one of the directories inside your home directory is called
Library. Let’s move there now, like so:
When you put a directory name after the
cd command, it assumes you want to move into that directory in your current location. If there doesn’t happen to be a directory called
Library in your current directory, you see an error message like this (preceded by
-bash if you’re using the
cd: Library: No such file or directory
As a reminder, the command-line environment doesn’t list the contents of a directory unless you ask it to (using
ls), so using
cd doesn’t automatically show what’s in your new location. You know the command succeeded if you don’t see an error message, and by default your prompt includes the name of your current directory.
Move Up or Down
Now that you’re in the
Library directory that’s in your home directory (
~/Library), you can use
ls to look around; you’ll see that one of the directories inside the current one is
Preferences. To move down a level into preferences, you’d enter
cd Preferences. And so on.
To go up a level, you use the
.. convention, which means “the directory that encloses this one.” For example, if you’re in
/Users/jk/Library/Preferences, the directory that encloses it is
/Users/jk/Library, so in this particular location two periods (
To get there, you enter:
That translates as “change directories to the one that encloses this one.” You can keep going up and down with
cd .. and
cd directory (fill in the name of any directory) as much as you like.
Move More Than One Level
Nothing says you have to move up or down just one level at a time. If you’re currently in
/Users/jk and you know that there’s a
Library directory inside it, and inside that there’s a
Preferences directory, you can jump directly to
Preferences like so:
The slash (
/) simply denotes that the term to its right is a directory inside the term on its left:
Preferences is a directory inside
Library. You can add on as many of these as you need:
This also works in the other direction. If you’re in
/Users/jk/Library/Preferences, you can enter
cd .. to move into
Library. Or, enter
cd ../.. to move directly into
cd ../../.. to move into
Move to an Exact Location
So far, we’ve been moving using relative locations—a directory inside the current one, or a directory that encloses the current one. But if you know exactly where you’re going, you can jump directly to any location on your Mac. Just specify the full path, beginning with a slash (
/), which represents the root level of your disk. For example, enter this:
That takes you directly to
/private/var/log (a rather boring directory full of—you guessed it—log files, and one that’s normally invisible in the Finder) without having to navigate all the way up to the root level of your disk and then back down.
Speaking of the root level: If you want to go to the very top of your disk hierarchy, just enter this:
Move Between Two Directories
Another handy shortcut, which lets you go back to the last directory you were in, is this:
For example, suppose I start in my home directory and then I enter
cd /Users/Shared. I do some things in that directory, and I next enter
cd ~/Library/Preferences to do other work there. If I then enter
cd - I jump back to
/Users/Shared (the last directory I was in), without having to type or even remember its path.
Once you’ve changed directories a few times, you may want to get back to your home directory. Of course, you could keep navigating up or down, one directory at a time, until you got there, or you could enter the complete path to your home directory (
cd /Users/jk, for example). But macOS has another shortcut (along the lines of
..) that means “the current user’s home directory”: the tilde (
So one way to jump home, from any location on your disk, is to enter:
But in fact, it can be even easier. If you enter
cd alone, with nothing after it, the command assumes you want to go home, so
cd by itself does the same thing as
Just as you can enter the full path after
cd to jump to any spot on your disk, you can substitute
~ whenever you’d otherwise use the full path to your home directory. So, even if you’re in
/private/var/tmp, you can go directly to the Library directory inside your home directory with:
Understand How Paths Work
You’ve already seen both relative paths (such as
Library/Preferences, which means the
Preferences directory inside the
Library directory inside my current directory) and absolute paths, which begin with a slash (such as
/Library/Preferences, which means the
Preferences directory inside the
Library directory at the top level of your disk). But there are a few other things you should understand about paths.
Spaces in Paths
macOS lets you put almost any character in a file or folder name, including spaces. But space characters can get you in trouble in the command-line environment, because normally a space separates commands, flags, and arguments.
Suppose you were to enter this:
cd My Folder
Even if there were a folder named
My Folder in the current directory, the command would produce an error message, because the
cd command would assume that both
Folder were intended to be separate arguments.
You can deal with spaces in either of two ways:
Quotation marks: One way is to put the entire path in quotation marks. For example, entering
cd "My Folder"would work fine.
Escape the space: The other way is to put a backslash (
\) before the space—this escapes the space character, making the shell treat it literally rather than as a separator between arguments. So this would also work:
cd My\ Folder.
Terminal automatically escapes the name of a file or folder when you drag it in from the Finder. See Get the Path of a File or Folder, later.
You can use wildcards when working on the command line; these can save you a lot of typing and make certain operations considerably easier. The two wildcards you’re most likely to use are these:
* (asterisk): This means “zero or more characters.” For example, if you want to switch to a directory called
Applications, you could enter
cd App*and, as long as there was no other directory there that started with those three letters, you’d go directly to the
Applicationsdirectory. (I talk about another way of doing something similar ahead a few pages in Use Tab Completion.)
You can use this wildcard with almost any command. For instance, if you’re in your home directory, you could type
ls D*to list all and only the items that begin with “D” (
? (question mark): This means “any single character.” That means
sat, and so on. If you have many files with similar names—say, sequentially numbered photos—you could limit the ones listed with something like
Here’s a trick question: is the macOS command line case-sensitive? The answer is yes—and no! Suppose you’re in
~. There’s a directory in there called
Pictures, and you could move into it in any of these ways (among others):
That certainly seems to suggest that the command line is not case-sensitive, because using either p or P has the same effect. But it’s possible to format a Mac volume to use a case-sensitive version of the APFS or Mac OS Extended (HFS+) file systems. If you do that—or if you connect to an external disk or network volume that uses a case-sensitive file system—then you could see both a
pictures directory and a
Pictures directory in the same place, in which case using the wrong case with the
cd command will take you to the wrong directory.
You won’t see any visual cue to let you know whether a particular volume uses a case-sensitive format. So the safest assumption is to always use the correct case: that always works.
Understand the macOS Directory Structure
You surely know from day-to-day use that your Mac has a bunch of standard folders at the top level of your startup disk—
Users, at minimum. You may have also noticed that each user’s home folder has its own
Library folder (not to mention a
Desktop folder, a
Documents folder, and several others). In addition to these and the numerous other folders you can see in the Finder, macOS has a long list of directories that are normally invisible (because most users never need to interact with them directly), but you can see them from the command line.
I could explain what every single (visible) folder and (hidden) directory is for, and how to make sense of the elaborate hierarchy in which macOS stores all its files. But that would take many pages and, honestly, it would be mighty boring. So I’m going to let you in on a little secret: you don’t have to know.
I mean it: you don’t have to know why one program is stored in
/bin while others are in
/usr/local/bin, or any of numerous other places. You don’t need to know why you have a
/dev directory or what goes in
/private/var. Seriously. Knowing all those things might be useful if you’re a programmer or a system administrator, but it’s absolutely irrelevant for ordinary folks who want to do the kinds of things discussed in this book. True, I may direct you to use a program in
/usr/sbin or modify a file in
/private/etc (or whatever), but as long as you can follow the instructions to do these things, you truly don’t have to know all the details about these directories.
So, instead, I want to provide a very short list of the key things you should understand about the macOS directory structure:
The invisible world of Unix: If you enter
ls -l /(go ahead and do that), you get a list of all the files and directories at the root level of your disk. You’ll see familiar names such as
Users, and some less-familiar ones, such as
usr. Here at the root level, directories that begin with a lowercase letter and aren’t shown in the Finder (such as
var), along with their contents, make up Darwin, the Unix core of macOS. Similar directories appear in other Unix and Unix-like operating systems.
Recursion, repetition, and recursion: If you were to work your way from the root of your disk down through all its directories and subdirectories, you’d notice a lot of names that appear over and over again. For example, there’s a top-level
/Librarydirectory, another inside
/System, and yet another inside each user’s home directory (
~/Library). Similarly, there are top-level
/sbindirectories, but also
/usr/sbin. The reasons for all these copies of similar-looking directories are sometimes practical, sometimes purely historical. But everything has its place.
You don’t have to grasp all the logic behind what goes where, but you do have to be sure you’re in the right place when you work on the command line. For instance, if an example in this book tells you to do something in
~/Library, be absolutely sure that’s where you are, as opposed to, say,
/Library. The smallest characters—in particular, the period (
.), tilde (
~), slash (
/), backslash (
\), and space (
The bandbox rule: My grandfather had a curious and oft-repeated expression: “Don’t monkey with the bandbox.” He (and, subsequently, my mother) used this to mean, approximately, “Don’t mess with something if you could break it and not be able to put it back together.” (As a child, I had quite a propensity for disassembling things and then getting stuck!)
On the command line, this means don’t go deleting, moving, or changing files if you don’t know what they are or what the consequences could be. Something that seems insignificant or useless to you could be crucial to the functioning of your Mac. (As a corollary, it should go without saying that you back up your Mac thoroughly and regularly—see my book Take Control of Backing Up Your Mac if you want detailed advice on the subject.)
Use Tab Completion
Because everything you do on the command line involves typing, it can get kind of tedious spelling out file and directory names over and over again—especially since even the slightest typo can make a command fail! So the
bash shells include a number of handy features to reduce the amount of typing you have to do. Earlier I explained how to use the arrow keys and the
!! command to repeat previous commands (Repeat a Command). Now I want to tell you about a different keystroke-saving technique: tab completion.
Here’s the basic idea. You start typing a file or directory name, and then you press the Tab key. If only one item in the current directory starts with the letter(s) you typed, the shell fills in the rest of that item’s name. If there’s more than one match, you’ll hear a beep; press Tab again to see a list of all the matches.
For example, try this:
Now that you’re in your home directory, type
cd De (without pressing Return) and press Tab. Your command line should look like this:
If you do want to change to your desktop directory, you can simply press Return. Or, you can type more on the line if need be. For now, let’s stay where we are—press Control-C to cancel the command.
Next, try typing
cd D (again, without pressing Return) and press Tab. You should hear a beep—signifying that there was more than one match—but nothing else should happen. Press Tab again. Now you’ll see something like this:
Desktop/ Documents/ Downloads/
And, on the previous line (in
zsh) or next line (in
bash), your command-in-progress appears again exactly as you left it off:
In this way, tab completion lets you know what your options are; you can type more letters (say,
oc) and press Tab again to have it fill in
Documents/ for you. In
zsh, you can keep pressing Tab to cycle through matching options, and press Return when the one you want appears.
Tab completion isn’t limited to just the current directory. For example, enter
cd ~/Lib and press Tab. The shell fills in the following:
Fav and press Tab. You should see
Favorites filled in:
You can keep going as many levels deep as you need to.
Find a File
In the command-line environment, as in the Finder, you may not know where to find a particular file or directory. Two commands can supply that information readily:
locate. Each has its pros and cons.
To use the
find command, you give it a name (or partial name) to look for and tell it where to start looking; the command then traverses every directory in the area you specify, looking at every single file until it finds a match. That makes it slow but thorough.
For example, suppose I want to find all the files anywhere in my home directory with names that contain the string keychain. I can do this:
find ~ -name "*keychain*"
After the command
~ tells the command to begin looking in my home directory (and work its way through all its subdirectories). The
-name flag says to look for patterns in the last item of a path (which may include the names of directories as well as files). I put the search string inside quotation marks, with an asterisk (
*) wildcard at the beginning and end to signify that there may be other letters before or after keychain.
Even a simple search such as this one can take several minutes, because it must look at every single file, starting at the path I specified. To make it go quicker, I could specify a narrower search range. For example, to have it look only in my
~/Library directory, I’d enter:
find ~/Library -name "*keychain*"
Let me offer a few other tips for using
To search in the current directory (and all subdirectories), use a period (
.) as the location:
find . -name "*keychain*".
To search your entire disk, use a slash (
/) as the location:
find / -name "*keychain*".
findis case-sensitive, so a search for
"*keychain*"would not match a file named Keychain. To make a search case-insensitive, replace
-iname, as in
find ~ -iname "*user data*".
During a search, if
findencounters any directories you don’t have permission to search, it displays the path of the directory with the message “Permission denied.” To search these paths, use
find, as described in Perform Actions as the Root User.
The other way to find files by name is to use the
locate command. Unlike
locate doesn’t traverse every file to find what you’re looking for. Instead, it relies on a database (index) of file and path names. The benefit of using the index is that
locate is lightning fast. The downside is, the database is normally updated only once a week, so
locate may be unable to find files you’ve added or renamed recently.
locate, just type that command followed by any portion of the filename you want to look for (no wildcards required). For example:
locate performs case-sensitive searches by default. To make a search case-insensitive, add the
locate -i keychain
If you enter
locate and get an error stating that no database exists—or if it exists but is outdated—you can create or update it by entering this:
The command may take some time to complete, because it does have to look at every file on your disk—or nearly so.
I’ve skipped over one important detail: by default,
locate indexes (and finds) only files you own (mostly the contents of your home directory). However, if you run the database updating script using
sudo (see Perform Actions as the Root User), it indexes every file on your disk, and
locate can therefore find every file.
The benefit of this is being able to find more files with
locate, but if you attempt to do this, a security warning appears informing you that once you’ve indexed all your files, any user of your Mac can discover the name and location (though not the contents) of any file on your disk. Moreover, the next time the
locate database updates on its weekly schedule, your system-wide index of files will be replaced with a version that contains only those you have permission to read.
View a Text File
You may not read a lot of plain text files in the Finder, but the need to do so comes up more frequently in the command-line environment—reading documentation, examining programs’ configurations, viewing shell scripts, inspecting logs, and numerous other situations. You can use many tools to read a file, of which I cover just a few here. (If you want to modify a text file, see Edit a Text File, later.)
You can use these commands with any text file on your Mac, but in these examples I use a file every Mac user should have: a dull Read Me file about OpenLDAP schema, located at
More or Less
An early Unix program for reading text files was called
more. It was pretty primitive and wouldn’t let you move backward to see earlier text. So a new program came along that was supposed to be the opposite of more:
less. In macOS, both names still exist, but they point to the same program; whether you enter
less, you’re actually running
less. (There are some subtle differences depending on which command you use, but they’re not worth mentioning.)
You can use
less to read a text file like this:
You see the top portion of the file initially. You can scroll down a line at a time using the ↓ key (and back up using the ↑ key), scroll ahead a screen at a time by pressing the Space bar, or backward a screen at a time by pressing the
B key (all by itself). To quit
less, press the
Q key (all by itself).
cat command (short for “concatenate”) combines files, but you can also use it to display a text file on your screen. Unlike
less, it doesn’t give you a paged view; it simply pours the entire contents of the file, regardless of length, onto your screen. You can then scroll the Terminal window up and down, as necessary, to view the contents. To use
cat, follow this pattern:
If you open a long text file with
less, it can take quite a bit of tapping on the Space bar to reach the end, which is awkward if the information you want happens to be at the end—as is the case with most logs. And if you use
cat, it can clutter your Terminal window with lots of information you don’t need. To jump to the end of a text file, use a different program:
tail, which displays the tail end of a file.
If you enter
tail followed by the filename, it displays the last 10 lines of the file:
tail command has flags that enable you to control how much of the file is shown and in what way, but for the sake of brevity I want to mention just one:
-n (number of lines). Type
tail followed by the
-n flag, a space, and a number to set the output to that number of lines from the end of the file:
tail -n 50 /etc/openldap/schema/README
Although the most interesting and useful stuff is more often at the end of a file, making
tail the quickest way to view it, sometimes you may want to look at the beginning of a file instead. For that purpose, use the opposite program:
If you enter
head followed by the filename, it displays the first 10 lines of the file:
To display a different number of lines, type
head followed by the
-n flag, a space, and a number:
head -n 50 /etc/openldap/schema/README
Almost every program and command you use on the command line has documentation that explains its syntax and options, and in many cases includes examples of how to use the command. This documentation isn’t always clear or helpful, but it’s worth consulting when you have a question. You can get at these manual pages in several ways.
In a Terminal Window
When you’re on the command line, the quickest way to get information about a command is to use the
man (“manual”) command. Simply enter
man followed by the command you want to learn about. For example:
The results appear in a viewer that works like
To put a slightly prettier (and scrollable) display of
man pages on the screen side by side with your working Terminal window, you can also click Terminal’s Help menu, type the name of a command in the Search field, select the item you want, and press Return. If the command is already visible anywhere in the Terminal window, you can right-click (or Control-click) it and choose “Open man Page” from the contextual menu to view it in a separate window. Or, if your cursor happens to be immediately to the right of the term you want to see the man page for, simply press ⌘-Control-?.
Clear the Screen
As you work in Terminal, your window may fill up with commands and their output. The command line itself is always the last line, but the rest of the window can become cluttered with the residue of earlier commands. Here are some ideas for decluttering the window:
If you find all that text distracting and want to clear the window (so it looks much like it did when you started the session), enter
clearor press Control-L. Terminal moves your command line up to the top of the window with empty space below it (you can still scroll up to see what was on the screen earlier).
To hide text that scrolled by in the Terminal window (perhaps to keep someone else from seeing what you did), press ⌘-K.
To clear the screen and prevent someone from scrolling back in Terminal to see your earlier activity (handy when you log out!), press ⌘-Option-K.
End a Shell Session
When you’re finished working on the command line for a while, you could simply close the Terminal window, or even quit Terminal, but you shouldn’t. That would be a bit like turning off your Mac by flipping the switch on the power strip instead of choosing Apple > Shut Down. The proper way to end a shell session in Terminal is to enter
exit, which gracefully stops any programs you are running in the shell, and then quits the shell program itself. (Starting in El Capitan, the
exit command also lists cleanup activities it performs, such as saving your latest session history and deleting older sessions.)
By default, your Terminal window remains open after you’ve done this. If you want it to close when you exit, choose Terminal > Preferences > Profiles > Current Profile Name > Shell. (Note: This setting was on the Settings pane in much older versions of macOS.) From the “When the shell exits” pop-up menu, choose “Close the window.”