Learn Enough to Be Dangerous
You have to make a choice. Choose...wisely.

Get occasional notifications about things like product discounts, blog posts, and new or updated tutorials. Unsubscribe at any time.

Gift Delivery Options
Quick Checkout
or Pay by Credit Card
Error processing your payment
  • You didn't choose whether or not to be added to the mailing list
Confirm
$0.00

Payments and credit card details are securely managed and protected by Learn Enough's payment processor, Stripe. More information on their site:

CART
Total
$0.00

Your Cart is Empty

$30
$300
$300
$XY
$XY
1234
  • Command Line

Learn Enough Society

Certificate of Course Completion

This page certifies that mhartl has completed Learn Enough Command Line to Be Dangerous! 🎉

About the tutorial
Learn Enough Command Line to Be Dangerous by Michael Hartl is an introduction to the Unix command line for complete beginners. Because the command line is a foundational technology for everything else in tech, this first Learn Enough tutorial is the best place to start learning to code. Read full post
14 Dec 12:49, 2015
11 Oct 11:57, 2016
Exercise Answers
Exercise Question:
  • Write a command that prints out the string “hello, world”. Extra credit: As in Listing 1.2, do it two different ways, both with and without using quotation marks.
  • mhartl's Answer:
    Exercise Question:
  • Type the command echo 'hello (with a mismatched single quote), and then get out of trouble using the technique from Box 1.3.
  • mhartl's Answer:
    Exercise Question:
  • According to the man page, what are the official short and long descriptions of echo on your system?
  • mhartl's Answer:
    Exercise Question:

    By reading the man page for echo, determine the command needed to print out “hello” without the trailing newline, and verify using your terminal that it works as expected. Hints: To determine the placement of the command-line option, it may help to refer to Figure 1.5. By comparing your result with Listing 1.5 and Listing 1.6, you should be able to verify that you’ve used the option properly. (Note: This exercise may fail when using the default terminal program on some older versions of macOS. In this case, I recommend installing iTerm (which isn’t a bad idea anyway).)

    mhartl's Answer:
    Exercise Question:
  • Using the up arrow, print to the screen the strings “fee”, “fie”, “foe”, and “fum” without retyping echo each time.
  • mhartl's Answer:
    Exercise Question:
  • By referring to Figure 1.5, identify the prompt, command, options, arguments, and cursor in each line of Figure 1.6.
  • mhartl's Answer:
    Exercise Question:
  • Most modern terminal programs have the ability to create multiple tabs (Figure 1.7), which are useful for organizing a set of related terminal windows.4 By examining the menu items for your terminal program (Figure 1.8), figure out how to create a new tab. Extra credit: Learn the keyboard shortcut for creating a new tab. (Learning keyboard shortcuts for your system is an excellent habit to cultivate.)
  • mhartl's Answer:
    Exercise Question:
  • Starting with the line in Listing 1.7, use any combination of ⌃A, ⌃E, arrow keys, or Option-click to change the occurrences of the short s to the archaic long s “ſ” in order to match the appearance of the original (Figure 1.11). In other words, the argument to echo should read “FRom faireſt creatures we deſire increaſe,”. Hint: It’s unlikely that your keyboard can produce “ſ” natively, so either copy it from the text of this tutorial or Google for it and copy it from the Internet. (If you have trouble copying and pasting into your terminal, I suggest applying the ideas in Box 1.4 to figure out how to do it on your system.)
  • mhartl's Answer:
    Exercise Question:
  • Clear the contents of the current tab.
  • mhartl's Answer:
    Exercise Question:
  • Open a new tab, execute echo 'hello', and then exit.
  • mhartl's Answer:
    Exercise Question:
  • Write a command to print the string Use "man echo", including the quotes; i.e., take care not to print out Use man echo instead. Hint: Use double quotes in the inner string, and wrap the whole thing in single quotes.
  • mhartl's Answer:
    Exercise Question:
  • By running man sleep, figure out how to make the terminal “sleep” for 5 seconds, and execute the command to do so.
  • mhartl's Answer:
    Exercise Question:
  • Execute the command to sleep for 5000 seconds, realize that’s well over an hour, and then use the instructions from Box 1.3 to get out of trouble.
  • mhartl's Answer:
    Exercise Question:
  • Using echo and >, make files called line_1.txt and line_2.txt containing the first and second lines of Sonnet 1, respectively.
  • mhartl's Answer:
    Exercise Question:
  • Replicate the original sonnet_1.txt (containing the first two lines of the sonnet) by first redirecting the contents of line_1.txt and then appending the contents of line_2.txt. Call the new file sonnet_1_copy.txt, and confirm using diff that it’s identical to sonnet_1.txt. Hint: When there is no diff between two files, diff simply outputs nothing.
  • mhartl's Answer:
    Exercise Question:
  • Use cat to combine the contents of line_1.txt and line_2.txt in reverse order using a single command, yielding the file sonnet_1_reversed.txt. Hint: The cat command can take multiple arguments.
  • mhartl's Answer:
    Exercise Question:
  • What’s the command to list all the non-hidden files and directories that start with the letter “s”?
  • mhartl's Answer:
    Exercise Question:
  • What is the command to list all the non-hidden files that contain the string “onnet”, long-form by reverse modification time? Hint: Use the wildcard operator at both the beginning and the end.
  • mhartl's Answer:
    Exercise Question:
  • What is the command to list all files (including hidden ones) by reverse modification time, in long form?
  • mhartl's Answer:
    Exercise Question:
  • Use the echo command and the redirect operator > to make a file called foo.txt containing the text “hello, world”. Then, using the cp command, make a copy of foo.txt called bar.txt. Using the diff command, confirm that the contents of both files are the same.
  • mhartl's Answer:
    Exercise Question:
  • By combining the cat command and the redirect operator >, create a copy of foo.txt called baz.txt without using the cp command.
  • mhartl's Answer:
    Exercise Question:
  • Create a file called quux.txt containing the contents of foo.txt followed by the contents of bar.txt. Hint: As noted in Section 2.1.1, cat can take multiple arguments.
  • mhartl's Answer:
    Exercise Question:
  • How do rm nonexistent and rm -f nonexistent differ for a nonexistent file?
  • mhartl's Answer:
    Exercise Question:
  • By copying and pasting the text from the HTML version of Figure 2.5, use echo to make a file called sonnet_1_complete.txt containing the full (original) text of Shakespeare’s first sonnet. Hint: You may recall getting stuck when echo was followed by an unmatched double quote (Section 1.3 and Box 1.3), as in echo ", but in fact this construction allows you to print out a multi-line block of text. Just remember to put a closing quote at the end, and then redirect to a file with the appropriate name. Check that the contents are correct using cat (Figure 2.2).
  • mhartl's Answer:
    Exercise Question:
  • Type the sequence of commands needed to create an empty file called foo, rename it to bar, and copy it to baz.
  • mhartl's Answer:
    Exercise Question:
  • What is the command to list only the files starting with the letter “b”? Hint: Use a wildcard.
  • mhartl's Answer:
    Exercise Question:
  • Remove both bar and baz using a single call to rm. Hint: If those are the only two files in the current directory that start with the letter “b”, you can use the wildcard pattern from the previous exercise.
  • mhartl's Answer:
    Exercise Question:
  • Use the command curl -I https://www.learnenough.com/ to fetch the HTTP header for the Learn Enough website. What is the HTTP status code for the address? How does this differ from the status code for learnenough.com (without the https://)?
  • mhartl's Answer:
    Exercise Question:
  • Using ls, confirm that sonnets.txt exists on your system. How big is it in bytes? Hint: Recall from Section 2.2 that the “long form” of ls displays a byte count.
  • mhartl's Answer:
    Exercise Question:
  • The byte count in the previous exercise is high enough that it’s more naturally thought of in kilobytes (often treated as 1000 bytes, but actually equal to \( 2^{10} = 1024 \) bytes). By adding the -h (“human-readable”) option to ls, list the long form of the sonnets file with a human-readable byte count.
  • mhartl's Answer:
    Exercise Question:
  • Suppose you wanted to list the files and directories using human-readable byte counts, all, by reverse time-sorted long-form. What command would you use? Why might this command be a personal favorite of the author of this tutorial?4
  • mhartl's Answer:
    Exercise Question:
  • By piping the results of tail sonnets.txt through wc, confirm that (like head) the tail command outputs 10 lines by default.
  • mhartl's Answer:
    Exercise Question:
  • By running man head, learn how to look at the first n lines of the file. By experimenting with different values of n, find a head command to print out just enough lines to display the first sonnet in its entirety (Figure 1.11).
  • mhartl's Answer:
    Exercise Question:
  • Pipe the results of the previous exercise through tail (with the appropriate options) to print out only the 14 lines composing Sonnet 1. Hint: The command will look something like head -n <i> sonnets.txt | tail -n <j>, where <i> and <j> represent the numerical arguments to the -n option.
  • mhartl's Answer:
    Exercise Question:
  • One of the most useful applications of tail is running tail -f to view a file that’s actively changing. This is especially common when monitoring files used to log the activity of, e.g., web servers, a practice known as “tailing the log file”. To simulate the creation of a log file, run ping learnenough.com > learnenough.log in one terminal tab. (The ping command “pings” a server to see if it’s working.) In a second tab, type the command to tail the log file. (At this point, both tabs will be stuck, so once you’ve gotten the gist of tail -f you should use the technique from Box 1.3 to get out of trouble.)
  • mhartl's Answer:
    Exercise Question:
  • Run less on sonnets.txt. Go down three pages and then back up three pages. Go to the end of the file, then to the beginning, then quit.
  • mhartl's Answer:
    Exercise Question:
  • Search for the string “All” (case-sensitive). Go forward a few occurrences, then back a few occurrences. Then go to the beginning of the file and count the occurrences by searching forward until you hit the end. Compare your count to the result of running grep All sonnets.txt | wc. (We’ll learn about grep in Section 3.4.)
  • mhartl's Answer:
    Exercise Question:
  • Using less and / (“slash”), find the sonnet that begins with the line “Let me not”. Are there any other occurrences of this string in the Sonnets? Hint: Press n to find the next occurrence (if any). Extra credit: Listen to the sonnet in both modern and original pronunciation. Which version’s rhyme scheme is better?
  • mhartl's Answer:
    Exercise Question:
  • Because man uses less, we are now in a position to search man pages interactively. By searching for the string “sort” in the man page for ls, discover the option to sort files by size. What is the command to display the long form of files sorted so the largest files appear at the bottom? Hint: Use ls -rtl as a model.
  • mhartl's Answer:
    Exercise Question:
  • By searching man grep for “line number”, construct a command to find the line numbers in sonnets.txt where the string “rose” appears.
  • mhartl's Answer:
    Exercise Question:
  • You should find that the last occurrences of “rose” is (via “roses”) on line 2203. Figure out how to go directly to this line when running less sonnets.txt. Hint: Recall from Table 3.1 that 1G goes to the top of the file, i.e., line 1. Similarly, 17G goes to line 17. Etc.
  • mhartl's Answer:
    Exercise Question:
  • The history command prints the history of commands in a particular terminal shell (subject to some limit, which is typically large). Pipe history to less to examine your command history. What was your 17th command?
  • mhartl's Answer:
    Exercise Question:
  • By piping the output of history to wc, count how many commands you’ve executed so far.
  • mhartl's Answer:
    Exercise Question:
  • One use of history is to grep your commands to find useful ones you’ve used before, with each command preceded by the corresponding number in the command history. By piping the output of history to grep, determine the number for the last occurrence of curl.
  • mhartl's Answer:
    Exercise Question:
  • In Box 3.1, we learned about !! (“bang bang”) to execute the previous command. Similarly, !n executes command number n, so that, e.g., !17 executes the 17th command in the command history. Use the result from the previous exercise to re-run the last occurrence of curl.
  • mhartl's Answer:
    Exercise Question:
  • What do the O and L options in Listing 3.1 mean? Hint: Pipe the output of curl -h to less and search first for the string -O and then for the string -L.
  • mhartl's Answer:
    Exercise Question:
  • Write in words how you might speak the directory ~/foo/bar.
  • mhartl's Answer:
    Exercise Question:
  • In /Users/bill/sonnets, what is the home directory? What is the username? Which directory is deepest in the hierarchy?
  • mhartl's Answer:
    Exercise Question:
  • For a user with username bill, how do /Users/bill/sonnets and ~/sonnets differ (if at all)?
  • mhartl's Answer:
    Exercise Question:
  • What is the option for making intermediate directories as required, so that you can create, e.g., ~/foo and ~/foo/bar with a single command? Hint: Refer to the man page for mkdir.
  • mhartl's Answer:
    Exercise Question:
  • Use the option from the previous exercise to make the directory foo and, within it, the directory bar (i.e., ~/foo/bar) with a single command.
  • mhartl's Answer:
    Exercise Question:
  • By piping the output of ls to grep, list everything in the home directory that contains the letter “o”.
  • mhartl's Answer:
    Exercise Question:
  • By piping the output of grep to head, print out the first (and only the first) line in sonnets.txt containing “rose”. Hint: Use the result of the second exercise in Section 3.2.2.
  • mhartl's Answer:
    Exercise Question:
  • In Listing 3.9, we saw two additional lines that case-insensitively matched “rose”. Execute a command confirming that both of the lines contain the string “Rose” (and not, e.g., “rOSe”). Hint: Use a case-sensitive grep for “Rose”.
  • mhartl's Answer:
    Exercise Question:
  • You should find in the previous exercise that there are three lines matching “Rose” instead of the two you might have expected from Listing 3.9. This is because there is one line that contains both “Rose” and “rose”, and thus shows up in both grep rose and grep -i rose. Write a command confirming that the number of lines matching “Rose” but not matching “rose” is equal to the expected 2. Hint: Pipe the result of grep to grep -v, and then pipe that result to wc. (What does -v do? Read the man page for grep (Box 1.4).)
  • mhartl's Answer:
    Exercise Question:
  • How do the effects of cd and cd ~ differ (or do they)?
  • mhartl's Answer:
    Exercise Question:
  • Change to text_files, then change to second_directory using the “one directory up” double dot operator ...
  • mhartl's Answer:
    Exercise Question:
  • From wherever you are, create an empty file called nil in text_files using whatever method you wish.
  • mhartl's Answer:
    Exercise Question:
  • Remove nil from the previous exercise using a different path from the one you used before. (In other words, if you used the path ~/text_files before, use something like ../text_files or /Users/<username>/text_files.)
  • mhartl's Answer:
    Exercise Question:
  • Make a directory foo with a subdirectory bar, then rename the subdirectory to baz.
  • mhartl's Answer:
    Exercise Question:
  • Copy all the files in text_files, with directory, into foo.
  • mhartl's Answer:
    Exercise Question:
  • Copy all the files in text_files, without directory, into bar.
  • mhartl's Answer:
    Exercise Question:
  • Remove foo and everything in it using a single command.
  • mhartl's Answer:
    Exercise Question:
  • Starting in your home directory, execute a single command-line command to make a directory foo, change into it, create a file bar with content “baz”, print out bar’s contents, and then cd back to the directory you came from. Hint: Combine the commands as described in Box 4.2.
  • mhartl's Answer:
    Exercise Question:
  • What happens when you run the previous command again? How many of the commands executed? Why?
  • mhartl's Answer:
    Exercise Question:
  • Explain why the command rm -rf / is unbelievably dangerous, and why you should never type it into a terminal window, not even as a joke.
  • mhartl's Answer:
    Exercise Question:
  • How can the previous command be made even more dangerous? Hint: Refer to Box 4.1. (This command is so dangerous you shouldn’t even think it, much less type it.)
  • mhartl's Answer:

    Join the Mailing List

    Get occasional notifications about things like product discounts, blog posts, and new or updated tutorials. Unsubscribe at any time.