Learn Enough Command Line
1 Basics
Figure 2: A prototypical command-line command.
1.1 Running a terminal
Figure 5: Anatomy of a command line. (Your prompt may differ.)
Figure 7: A terminal window with three tabs.
Figure 8: Some menu items for the default macOS terminal.
keyboard shortcut: ⌃T
1.2 Our first command
$ echo hello
hello
$
double quotes, single quotes
$ echo "goodbye"
goodbye
$ echo 'goodbye'
goodbye
$
Listing 1: Printing “hello, goodbye” two different ways.
$ echo hello, goodbye
hello, goodbye
$ echo "hello, goodbye"
hello, goodbye
$
One thing that can happen when using quotes is accidentally not matching them, as follows:
$ echo "hello, goodbye
>
keyboard shortcut:
Ctrl-C
Get out of trouble
Figure 9: This cat appears to be stuck and should probably hit Ctrl-C
.
1.3 Man pages
Listing 2: The result of running man echo.
$ man echo
ECHO(1) BSD General Commands Manual ECHO(1)
NAME
echo -- write arguments to the standard output
SYNOPSIS
echo [-n] [string ...]
DESCRIPTION
The echo utility writes any specified operands, separated by single blank
(` ') characters and followed by a newline (`\n') character, to the stan-
dard output.
The following option is available:
-n Do not print the trailing newline character. This may also be
achieved by appending `\c' to the end of the string, as is done by
iBCS2 compatible systems. Note that this option as well as the
effect of `\c' are implementation-defined in IEEE Std 1003.1-2001
(``POSIX.1'') as amended by Cor. 1-2002. Applications aiming for
maximum portability are strongly encouraged to use printf(1) to
suppress the newline character.
:
on any system you should be able to access subsequent information one line at a time by pressing the down arrow key, or one page at a time by pressing the spacebar. To exit the man page, press “q” (for “quit”).
Figure 10: Applying man
to man
.
Listing 3: The result of running man man.
$ man man
man(1) man(1)
NAME
man - format and display the on-line manual pages
SYNOPSIS
man [-acdfFhkKtwW] [--path] [-m system] [-p string] [-C config_file]
[-M pathlist] [-P pager] [-B browser] [-H htmlpager] [-S section_list]
[section] name ...
DESCRIPTION
man formats and displays the on-line manual pages. If you specify sec-
tion, man only looks in that section of the manual. name is normally
the name of the manual page, which is typically the name of a command,
function, or file. However, if name contains a slash (/) then man
interprets it as a file specification, so that you can do man ./foo.5
or even man /cd/foo/bar.1.gz.
See below for a description of where man looks for the manual page
files.
OPTIONS
-C config_file
:
man [-acdfFhkKtwW] [--path] [-m system] [-p string] ...
Figure 11: “Tech Support Cheat Sheet” (via xkcd). See Box 5 for three extra techniques.
1.4 Editing the line
Key | Symbol |
---|---|
Command | ⌘ |
Control | ⌃ |
Shift | ⇧ |
Option | ⌥ |
Up, down, left, right | ↑ ↓ ← → |
Enter/Return | ↵ |
Tab | ⇥ |
Delete | ⌫ |
Table 1: Miscellaneous keyboard symbols.
If you're using a keyboard made for Windows PCs, use the Alt key instead of Option, and the Windows logo key instead of Command.
keyboard shortcut:
⌃A
Move to beginning of line⌃E
Move to end of line⌃U
Delete to beginning of line
1.5 Cleaning up
$ clear
keyboard shortcut: ⌃L
$ exit
keyboard shortcut: ⌃D
1.6 Summary
Command | Description | Example |
---|---|---|
echo <string> |
Print string to screen | $ echo hello |
man <command> |
Display manual page for command | $ man echo |
⌃C |
Get out of trouble | $ tail ^C |
⌃A |
Move to beginning of line | |
⌃E |
Move to end of line | |
⌃U |
Delete to beginning of line | |
Option-click | Move cursor to location clicked | |
Up & down arrow | Scroll through previous commands | |
clear or ⌃L |
Clear screen | $ clear |
exit or ⌃D |
Exit terminal | $ exit |
Table 2: Important commands from Section 1.
2 Manipulating files
Figure 13: It’s not a bug, it’s a feature.
2.1 Redirecting and appending
$ echo "From fairest creatures we desire increase,"
From fairest creatures we desire increase,
redirect operator >
:
$ echo "From fairest creatures we desire increase," > sonnet_1.txt
$ cat sonnet_1.txt
From fairest creatures we desire increase,
Figure 14: Viewing a file with cat.
append operator >>
:
$ echo "That thereby beauty's Rose might never die," >> sonnet_1.txt
cat
: “concatenate”
$ cat sonnet_1.txt
From fairest creatures we desire increase,
That thereby beauty's Rose might never die,
$ echo "From fairest creatures we desire increase," > sonnet_1_lower_case.txt
$ echo "That thereby beauty's rose might never die," >> sonnet_1_lower_case.txt
diff
$ diff sonnet_1.txt sonnet_1_lower_case.txt
2c2
< That thereby beauty's Rose might never die,
---
> That thereby beauty's rose might never die,
2.2 Listing
Listing 8: Listing files and directories with ls. (Output will vary.)
$ ls
Desktop
Downloads
sonnet_1.txt
sonnet_1_reversed.txt
Figure 15: The graphical equivalent of ls
.
Listing 9: Running ls on a nonexistent file.
$ ls foo
ls: foo: No such file or directory
$ touch foo
$ ls foo
foo
wildcard character *
:
$ ls *.txt
sonnet_1.txt
sonnet_1_reversed.txt
$ ls -l *.txt
total 16
-rw-r--r-- 1 mhartl staff 87 Jul 20 18:05 sonnet_1.txt
-rw-r--r-- 1 mhartl staff 294 Jul 21 12:09 sonnet_1_reversed.txt
ls -rtl
: “list by reversed time of modification (long format)”
$ ls -rtl
Hidden files
ignore all files ending in “.txt”
$ echo "*.txt" > .gitignore
$ cat .gitignore
*.txt
$ ls
sonnet_1.txt
sonnet_1_reversed.txt
$ ls -a
. .gitignore sonnet_1_reversed.txt
.. sonnet_1.txt
2.3 Renaming, copying, deleting
rename a file
mv
: “move”
$ echo "test text" > test
$ mv test test_file.txt
$ ls
test_file.txt
copy a file
cp
: “copy”
$ cp test_file.txt second_test.txt
$ ls
second_test.txt
test_file.txt
deleting a file
rm
: “remove”
$ rm -i second_test.txt
remove second_test.txt? y
$ ls second_test.txt
ls: second_test.txt: No such file or directory
Box 8. Tab completion
$ rm tes⇥
$ ls foo⇥
$ ls f⇥⇥
remove all the files ending with “.txt”
-f
: “force”
$ rm -f *.txt
Unix terseness
instead of list
, move
, copy
, and remove
, we have ls
, mv
, cp
, and rm
.
Figure 16: The terseness of Unix commands can be a source of confusion.
2.4 Summary
Command | Description | Example |
---|---|---|
> |
Redirect output to filename | $ echo foo > foo.txt |
>> |
Append output to filename | $ echo bar >> foo.txt |
cat <file> |
Print contents of file to screen | $ cat hello.txt |
diff <f1> <f2> |
Diff files 1 & 2 | $ diff foo.txt bar.txt |
ls |
List directory or file | $ ls hello.txt |
ls -l |
List long form | $ ls -l hello.txt |
ls -rtl |
Long by reverse modification time | $ ls -rtl |
ls -a |
List all (including hidden) | $ ls -a |
touch <file> |
Create an empty file | $ touch foo |
mv <old> <new> |
Rename (move) from old to new | $ mv foo bar |
cp <old> <new> |
Copy old to new | $ cp foo bar |
rm <file> |
Remove (delete) file | $ rm foo |
rm -f <file> |
Force-remove file | $ rm -f bar |
Table 3: Important commands from Section 2.
3 Inspecting files
3.1 Downloading a file
$ which curl
/usr/bin/curl
Listing 10: Using curl to download a longer file.
$ curl -OL cdn.learnenough.com/sonnets.txt
$ ls -rtl
Box 9. Repeating previous commands
exclamation point : !
$ echo "foo"
foo
$ !!
echo "foo"
foo
$ !curl
⌃R
$ <⌃R>
(reverse-i-search)`curl': curl -OL cdn.learnenough.com/sonnets.txt
3.2 Making heads and tails of it
head
and tail
Listing 11: Looking at the head of the sample text file.
$ head sonnets.txt
Shake-speare's Sonnets
I
From fairest creatures we desire increase,
That thereby beauty's Rose might never die,
But as the riper should by time decease,
His tender heir might bear his memory:
But thou contracted to thine own bright eyes,
Feed'st thy light's flame with self-substantial fuel
Listing 12: Looking at the tail of the sample text file.
$ tail sonnets.txt
The fairest votary took up that fire
Which many legions of true hearts had warm'd;
And so the general of hot desire
Was, sleeping, by a virgin hand disarm'd.
This brand she quenched in a cool well by,
Which from Love's fire took heat perpetual,
Growing a bath and healthful remedy,
For men diseas'd; but I, my mistress' thrall,
Came there for cure and this by that I prove,
Love's fire heats water, water cools not love.
Wordcount and pipes
wc
$ wc sonnets.txt
2620 17670 95635 sonnets.txt
lines, words, and bytes
Listing 13: Redirecting head
and running wc
on the result.
$ head sonnets.txt > sonnets_head.txt
$ wc sonnets_head.txt
10 46 294 sonnets_head.txt
Listing 14: Piping the result of head
through wc
.
$ head sonnets.txt | wc
10 46 294
3.3 Less is more
more
, less
$ less sonnets.txt
Shake-speare's Sonnets
I
From fairest creatures we desire increase,
That thereby beauty's Rose might never die,
But as the riper should by time decease,
His tender heir might bear his memory:
But thou contracted to thine own bright eyes,
Feed'st thy light's flame with self-substantial fuel,
Making a famine where abundance lies,
Thy self thy foe, to thy sweet self too cruel:
Thou that art now the world's fresh ornament,
And only herald to the gaudy spring,
Within thine own bud buriest thy content,
And tender churl mak'st waste in niggarding:
Pity the world, or else this glutton be,
To eat the world's due, by the grave and thee.
II
When forty winters shall besiege thy brow,
And dig deep trenches in thy beauty's field,
sonnets.txt
Search file for string
Shake-speare's Sonnets
I
From fairest creatures we desire increase,
That thereby beauty's Rose might never die,
But as the riper should by time decease,
His tender heir might bear his memory:
But thou contracted to thine own bright eyes,
Feed'st thy light's flame with self-substantial fuel,
Making a famine where abundance lies,
Thy self thy foe, to thy sweet self too cruel:
Thou that art now the world's fresh ornament,
And only herald to the gaudy spring,
Within thine own bud buriest thy content,
And tender churl mak'st waste in niggarding:
Pity the world, or else this glutton be,
To eat the world's due, by the grave and thee.
II
When forty winters shall besiege thy brow,
And dig deep trenches in thy beauty's field,
/rose
Command | Description | Example |
---|---|---|
up & down arrow keys |
Move up or down one line | |
spacebar |
Move forward one page | |
⌃F |
Move forward one page | |
⌃B |
Move back one page | |
G |
Move to end of file | |
1G |
Move to beginning of file | |
/<string> |
Search file for string | /rose |
n |
Move to next search result | |
N |
Move to previous search result | |
q |
Quit less |
Table 4: The most important less
commands.
3.4 Grepping
Listing 16: Finding the occurrences of “rose” in Shakespeare’s sonnets.
$ grep rose sonnets.txt
The rose looks fair, but fairer we it deem
As the perfumed tincture of the roses.
Die to themselves. Sweet roses do not so;
Roses of shadow, since his rose is true?
Which, like a canker in the fragrant rose,
Nor praise the deep vermilion in the rose;
The roses fearfully on thorns did stand,
Save thou, my rose, in it thou art my all.
I have seen roses damask'd, red and white,
But no such roses see I in her cheeks;
Listing 17: Piping the results of grep
to wc
.
$ grep rose sonnets.txt | wc
10 82 419
case-insensitive matching
- Type
man grep
- Type
/case
and then return - Read off the result (Figure 19)
Figure 19: The result of searching man grep for “case”.
3.5 Summary
Command | Description | Example |
---|---|---|
curl |
Interact with URLs | $ curl -O example.com |
which |
Locate a program on the path | $ which curl |
head <file> |
Display first part of file | $ head foo |
tail <file> |
Display last part of file | $ tail bar |
wc <file> |
Count lines, words, bytes | $ wc foo |
`cmd1 | cmd2` | Pipe cmd1 to cmd2 |
ping <url> |
Ping a server URL | $ ping google.com |
less <file> |
View file contents interactively | $ less foo |
grep <string> <file> |
Find string in file | $ grep foo bar.txt |
grep -i <string> <file> |
Find case-insensitively | $ grep -i foo bar.txt |
ps |
Show processes | $ ps aux |
top |
Show processes (sorted) | $ top |
kill -<level> <pid> |
Kill a process | $ kill -15 24601 |
pkill -<level> -f <name> |
Kill matching processes | $ pkill -15 -f spring |
Table 5: Important commands from Section 3.
4 Directories
4.1 Directory structure
$ ls /Users/mhartl/ruby
$ ls /usr/local/bin
Figure 20: The correspondence between folders & directories.
Box 11. “sudo make me a sandwich.”
$ touch /opt/foo
touch: /opt/foo: Permission denied
$ sudo touch /opt/foo
Password:
$ ls -l /opt/foo
-rw-r--r-- 1 root wheel 0 3 14 00:21 /opt/foo
$ rm -f /opt/foo
rm: /opt/foo: Permission denied
$ sudo !!
sudo rm -f /opt/foo
$ !ls
ls -l /opt/foo
ls: /opt/foo: No such file or directory
4.2 Making directories
mkdir
: “make directory”
$ mkdir text_files
$ mv *.txt text_files/
$ ls text_files/
sonnet_1.txt sonnet_1_reversed.txt sonnets.txt
$ ls -d text_files/
text_files/
ls -ld text_files/
drwxr-xr-x 4 wuyong staff 136 3 14 00:50 text_files/
$ cd text_files/
cd tex⇥
pwd
: “print working directory”
$ pwd
/Users/mhartl/text_files
$ ls
sonnet_1.txt sonnet_1_reversed.txt sonnets.txt
4.3 Navigating directories
$ pwd
/Users/mhartl/text_files
$ cd ..
$ pwd
/Users/mhartl
Change to home directory
$ cd
$ cd ~
$ pwd
/Users/mhartl
$ mkdir second_directory
$ cd second_directory/
$ pwd
/Users/mhartl/second_directory
$ cd ~/text_files
$ pwd
/Users/mhartl/text_files
moving or copying files to the current directory:
$ pwd
/Users/mhartl/text_files
$ cd ~/second_directory
$ ls
$ cp ~/text_files/sonnets.txt .
$ ls
sonnets.txt
.
, find
$ cd
$ find . -name '*.txt'
./text_files/sonnet_1.txt
./text_files/sonnet_1_reversed.txt
./text_files/sonnets.txt
Perhaps my favorite use of . is in “open dot”, which will work only on macOS:
$ cd ~/ruby/projects
$ open .
to the previous directory
$ pwd
/Users/mhartl/second_directory
$ cd ~/text_files
$ pwd
/Users/mhartl/text_files
$ cd -
/Users/mhartl/second_directory
Box 12. Combining commands
$ ./configure ; make ; make install
$ ./configure && make && make install
The difference is that commands separated by &&
run only if the previous command succeeded. In contrast, with ;
all the commands will be run no matter what, which will cause an error in the likely case that subsequent commands depend on the results of the ones that precede them.
4.4 Renaming, copying, and deleting directories
$ mkdir foo
$ mv foo/ bar/
$ cd foo/
-bash: cd: foo: No such file or directory
$ cd bar/
$ cd
$ mv bar foo
$ cd foo/
Listing 19: Copying a directory.
$ cd
$ mkdir foobar
$ cd foobar/
$ cp -r ../text_files .
$ ls
text_files
Listing 20: Copying with a trailing slash.
$ cp -r ../text_files/ .
$ ls
sonnet_1.txt sonnet_1_reversed.txt sonnets.txt text_files
$ cp ../text_files/* .
rmdir
$ cd
$ rmdir second_directory
rmdir: second_directory/: Directory not empty
rm -rf
: “remove recursive force”
$ rm -rf second_directory/
$ ls second_directory
ls: second_directory: No such file or directory
Figure 22: This superhero understands how to use the power of rm -rf
responsibly.
Grep redux
$ cd text_files/
$ mkdir foo
$ cd foo/
$ echo sesquipedalian > long_word.txt
$ cd
$ grep sesquipedalian text_files
grep: text_files: Is a directory
$ grep -r sesquipedalian text_files
text_files/foo/long_word.txt:sesquipedalian
$ grep -ri sesquipedalian text_files
text_files/foo/long_word.txt:sesquipedalian
4.5 Summary
Command | Description | Example |
---|---|---|
mkdir <name> |
Make directory with name | $ mkdir foo |
pwd |
Print working directory | $ pwd |
cd <dir> |
Change to |
$ cd foo/ |
cd ~/<dir> |
cd relative to home | $ cd ~/foo/ |
cd |
Change to home directory | $ cd |
cd - |
Change to previous directory | $ cd && pwd && cd - |
. |
The current directory | $ cp ~/foo.txt . |
.. |
One directory up | $ cd .. |
find |
Find files & directories | $ find . -name foo*.* |
cp -r <old> <new> |
Copy recursively | $ cp -r ~/foo . |
rmdir <dir> |
Remove (empty) dir | $ rmdir foo/ |
rm -rf <dir> |
Remove dir & contents | $ rm -rf foo/ |
grep -ri <string> <dir> |
Grep recursively (case-insensitive) | $ grep -ri foo bar/ |
Table 6: Important commands from Section 4.