- Part 1 – First Steps in Terminal
- Part 2 – Navigating the File System
- Part 3 – Special Characters
- Part 4 – Commands
- Part 5 – Managing Files
- Part 6 – Symbolic Links
If you like this series and want to learn Terminal and the shell on macOS in more detail, get my book “macOS Terminal and Shell“
Working Directory
Back to our earlier example, the pwd
command. You entered the command pwd
and the shell returned a result:
$ pwd
/Users/armin
Your output will be different. Unless your name is also armin
, the path will end with your user name, not mine. Depending on the configuration of your Mac, your path might be entirely different.
pwd
is short for ‘print working directory.’ It shows the folder this shell is currently working in, much like a Finder window displays the contents of a certain folder.
On macOS, Terminal will also show the working directory in the window title bar.
Paths
Modern file systems are hierarchical and have many folders and files nested in each other. In a Unix shell you denote a folder or file in another folder with the forward ‘/
’ slash character. The complete series of folders to a file or folder is called its ‘path.’
For example, if there is a file hello.txt
in your Documents folder in your home directory, its complete path or absolute path is:
/Users/armin/Documents/hello.txt
A path starts at the ‘root’ of the file system, which is shown as simply /
. On macOS the root of the file system is the top level of the volume or disk with the active system, i.e. the current startup volume of the Mac.
Note: The file system root
/
should not be confused with the system userroot
.
This path tells me (and the shell) that there is a file ‘hello.txt’ in a folder ‘Documents’ in a folder ‘armin’ in a folder ‘Users’ on the root of the file system, the current startup volume.
Note: Finder in macOS and other graphical interfaces use the word ‘folder.’ Unix and other command line shells use the word ‘directory.’ They are the same.
Relative Paths
Addressing files and folders with their full path each and every time would be very tedious. To help with that a shell has a ‘current working directory.’
You can refer to files and folder relative to the shell’s current working directory. When using relative paths, there is no initial /
.
hello.txt
refers to the file ‘hello.txt’ in the current working directory.
Documents/hello.txt
refers to the file ‘hello.txt.’ in the folder ‘Documents’ in the current working directory.
Relative paths do not have a leading /
and are relative to the current working directory. Full paths start with a /
and are based in the file system root. Full paths are also called ‘absolute’ paths.
It is surprisingly easy to lose track of the current working directory. You can ask the shell for the current working directory with the pwd
command.
Mac:~ armin$ pwd
/Users/armin
Changing Directories
You can change the current working directory with the cd
command (change directory):
Mac:~ armin$ cd Documents
Mac:Documents armin$ pwd
/Users/armin/Documents
Use the cd
command with a relative path Documents
and the shell changes it working directory there. The pwd command prints the full path of the working directory.
You can also navigate to an absolute path:
Mac:Documents armin$ cd /Library
Mac:Library armin$ pwd
/Library
Mac:Library armin$ cd /
Mac:/ armin$ pwd
/
You may have noticed that the prompt displays the name of the current directory. This helps you remember your ‘bearings’ in terminal. Terminal on macOS will also display the current working directory in the window title bar.
You can open a second terminal window by selecting ‘New Window with Settings – Basic’ from the ‘New Window’ menu in the ‘Shell’ menu. It is easier to remember the ⌘N (command-N) keystroke. If you prefer you can also open new shells in a new Tab with ⌘T.
The second window or tab will start a second, new bash
shell. This shell is entirely separate of the first bash
shell. Different shells will have different working directories. They are very much like different windows showing different folder contents in the Finder.
Home Directory
The prompt in the second terminal window will show:
Mac:~ armin$
According to the prompt current working directory is ~
?
The tilde ~
is a special character in bash
and other shells. It is a shortcut for the user’s home directory or home folder. On macOS a user’s home directory is created in the /Users
directory with the user’s short name as the directory name. So if my short name is ‘armin’ my home directory is /Users/armin
.
So the ~
in the prompt says the current working directory is my home folder.
Mac:~ armin$ pwd
/Users/armin
Note: It is important that the shell will actually substitute a
~
with the home directory path before executing the command.
You can use the ~
with cd
to quickly change the working directory to your home directory
$ cd ~
$ pwd
/Users/armin
You don’t have to use this, though, since cd
without any arguments, will change to your home directory.
$ cd
$ pwd
/Users/armin
You can also start a path with ~
:
$ cd ~/Documents
$ pwd
/Users/armin/Documents
Since ~
is replaced with an absolute path to the home directory, paths that start with ~
are absolute as well.
Moving On Up
You can change the working directory into subdirectories and you can change to absolute paths.
You also often want to move up one level in the folder hierarchy, to the parent folder of the current folder.
Now you could remember your current location (or recall it with pwd
) and cd
to the absolute path of the parent manually. However, there is an easier way to do this:
$ cd ~/Documents/
$ pwd
/Users/armin/Documents
$ cd ..
$ pwd
/Users/armin
In bash
(and most other shells) two periods ..
represent the parent directory of the current working directory.
You can even use ..
multiple times:
$ cd ~/Library/Preferences/ByHost
$ cd ../..
$ pwd
/Users/armin/Library
../..
designates the parent directory of the parent. ../../..
goes up three levels, etc.
Note: if you
cd /
and thencd ..
nothing happens.
Moving Back
The shell remembers the last working directory, as well, even if you don’t. You can quickly switch back to the previous working directory with cd -
(minus):
$ cd ~/Documents
$ cd /Library/Preferences
$ cd -
/Users/armin/Documents
Documents $ cd -
/Library/Preferences
To assist orientation, cd -
will print the full path to the directory it is changing to.
Tab Completion
Typing paths is tedious and error prone. Errors in paths can lead to simple errors and frustration, and sometimes typos can have catastrophic results.
When you are typing commands, file names or paths in bash, then you can use the tab key ⇥ to save keystrokes and avoid typos.
For example, you can type:
$ cd ~/Doc⇥
and it will complete to
$ cd ~/Documents/
Tab completion will add a forward slash /
to the end of a directory’s name so you can continue typing the next directory name. You can hit tab over and over at different parts of the command:
$ cd ~/Li⇥
$ cd ~/Library/
$ cd ~/Library/Appl⇥
$ cd ~/Library/Application\ S<beep>
$ cd ~/Library/Application\ Su⇥
$ cd ~/Library/Application\ Support/
When there are multiple options to complete, bash
will complete as far as it is unambiguous and will play an alarm sound. When you then press tab for the second time, it will list all options:
$ cd ~/D⇥<beep>⇥
Desktop/ Documents/ Downloads/
Using tab-completion not only saves keystrokes and time, but also reduces the potential for typos and errors.
You may have noted that tab completion did something strange to the space in the path of the ‘Application Support’ folder. There are many special characters that you have to deal with in the shell. Space is one of them. We will learn how to deal with space and the other special characters in the next section.
Note: commands, arguments and file names in bash are case-sensitive. However, since the macOS filesystems (HFS+ and APFS) are case-insensitive by default, you may want to switch tab-completion to be case-insensitive as well , too.
Listing Directory Contents
The next command is ls
, which is short for ‘list’.
$ cd ~
$ ls
Desktop Downloads Movies Pictures
Documents Library Music Public
This command will list the contents of the current working directory. The contents of your home directory may be different.
To use the space efficiently ls
prints the files and folders in multiple columns (the number of columns depends on the size of your Terminal window).
This simple list can be very useful to lookup file and directory names. However, you cannot tell the difference between files and directories in this list.
You can tell ls
to show an extra character to indicate the kind of an entry:
$ ls -F
Desktop/ Downloads/ Movies/ Pictures/
Documents/ Library/ Music/ Public/
This version of ls output will add a slash ‘/’ to directories and an asterisk ‘*’ to executable files. Normal files (documents) will have no extra character.
In this command the -F
is an option for the ls command. Options are a special kind of argument. Options usually start with one or two a hyphen characters -
and are followed by a letter. Generally options work like switches to turn certain features of the command on or off.
Since the shell is case-sensitive the options -F
and -f
are different.
Since ls
is a very common command, it has many options. The -G
option works similar to the -F
option but marks the different kinds with colors:
You can use multiple options at once:
$ ls -G -F
Desktop/ Downloads/ Movies/ Pictures/
Documents/ Library/ Music/ Public/
With most commands you can combine multiple options after a single hyphen: ls -GF
is the same as ls -G -F
You can also add an argument to ls
:
$ ls ~/Desktop
will list the contents of the Desktop
directory without changing the working directory. You can combine options and an argument. When you do that you usually put the options before the argument.
$ ls -GF ~/Desktop
Detailed List
The default output of ls is very terse. You can get more information by adding the -l
(lower-case L
) option.
$ ls -l
total 0
drwx------+ 6 armin staff 204 Jul 18 17:22 Desktop
drwx------+ 3 armin staff 102 Jun 6 11:24 Documents
drwx------+ 3 armin staff 102 Jun 6 11:24 Downloads
drwx------@ 50 armin staff 1700 Jul 18 16:02 Library
drwx------+ 3 armin staff 102 Jun 6 11:24 Movies
drwx------+ 3 armin staff 102 Jun 6 11:24 Music
drwx------+ 3 armin staff 102 Jun 6 11:24 Pictures
drwxr-xr-x+ 5 armin staff 170 Jun 6 11:24 Public
This command lists one file or directory per line. The columns are (in order):
- file type and mode
- first character shows type: (d directory, l link, – file)
- number of links
- file owner
- file group
- file size in bytes
- modification date and time
- name
There are more options that you can use with the -l
option. For example the -h
option will show file sizes with B (bytes), K (kilobytes), M (megabytes) etc. instead of raw bytes.
You can also combine -l
with -G
and/or -F
.
Invisible Files
Certain files and directories that are invisible in Finder are visible in the shell. The ~/Library
folder has been hidden in the Finder since Mac OS X 10.7 Lion, but is easily visible with ls
. By convention however, ls
does not usually list files and directories that start with a dot or period .
. You can make ls show these files with the -a
option. Your home directory will already have a few ‘dot-files’:
$ ls -al ~
total 16
drwxr-xr-x+ 15 armin staff 510 Jul 18 15:30 .
drwxr-xr-x 7 root admin 238 Jul 19 08:35 ..
drwx------ 4 armin staff 136 Jul 19 14:55 .Trash
-rw------- 1 armin staff 402 Jul 19 08:39 .bash_history
drwx------ 3 armin staff 102 Jul 13 09:16 .ssh
drwx------+ 8 armin staff 272 Jul 19 14:57 Desktop
drwx------+ 3 armin staff 102 Jun 6 11:24 Documents
drwx------+ 3 armin staff 102 Jun 6 11:24 Downloads
drwx------@ 50 armin staff 1700 Jul 18 16:02 Library
drwx------+ 3 armin staff 102 Jun 6 11:24 Movies
drwx------+ 3 armin staff 102 Jun 6 11:24 Music
drwx------+ 3 armin staff 102 Jun 6 11:24 Pictures
drwxr-xr-x+ 5 armin staff 170 Jun 6 11:24 Public
In UNIX files and directories that start with a period are commonly used to store configuration data.
The first two entries in this list are .
and ..
. We already know that ..
represents the parent directory (in this case of the directory listed). The single period .
is another convention that represents the current directory or (in this case the directory listed). This can be useful to see the file mode and owner of these directories right here.
Note: Finder also follows this convention and hides ‘dotfiles’ by default. You can learn more about hidden files and folders in this article.
Summary
So far we have encountered three commands to navigate the file system: pwd
, cd
, and ls
pwd
prints the current working directory.
$ pwd
/Users/armin/Documents
cd
changes the working directory to another.
You can use absolute paths (that begin with /
):
$ cd /Library/Application\ Support
$ cd /
or paths relative to the current working directory (no leading /
):
$ cd Documents
Two periods ..
represent the parent directory:
$ cd ..
changes the working directory to the parent directory.
The tilde ~
represents your home directory. You can use it alone or to start a path to folders and files in your home directory.
$ cd ~
$ cd ~/Documents
The ls
command lists the contents of the current working directory:
$ ls
Desktop Downloads Movies Pictures
Documents Library Music Public
The ls
command has many options. The most commonly used are probably -l
to show a detailed list of the files and folders and -a
to also show the files and directories starting with a period, which are usually hidden.
Next: Special Characters