It is vacation time here in the Scripting OS X headquarters and I will be traveling with family for most of August. The Weekly News Summaries are also on vacation, but to compensate for that I will be posting a draft of parts of my next book on macOS Terminal and
bash. Let me know how you like them or if you think something important is wrong or missing. You can give feedback in the comments, over Twitter or in the MacAdmins forum (also scriptingosx). Thank you for your interest and feedback!
- First Steps in Terminal
- Navigating the File System (this post)
- Special Characters
- Managing Files
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.
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:
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 user
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.
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
refers to the file ‘hello.txt’ in the current working directory.
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
Mac:~ armin$ pwd /Users/armin
You can change the current working director with the
cd command (change directory):
Mac:~ armin$ cd Documents Mac:Documents armin$ pwd /Users/armin/Documents
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.
The prompt in the second terminal window will show:
According to the prompt current working directory is
~ 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
~ 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
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
~ 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
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
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 then
cd ..nothing happens.
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.
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 are different.
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 ~/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
The default output of ls is very terse. You can get more information by adding the
$ 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
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
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
... 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.
So far we have encountered three commands to navigate the file system:
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
.. represent the parent directory:
$ cd ..
changes the working directory to the parent directory.
~ 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
ls command lists the contents of the current working directory:
$ ls Desktop Downloads Movies Pictures Documents Library Music Public
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