-2

Having done these previous steps:

  1. Created a new directory called missing under /tmp.
  2. Used touch to create a new file called semester in missing.

How do I write the following into that file, one line at a time?

#!/bin/sh
curl --head --silent https://missing.csail.mit.edu

On the website where this exercise was posted, it mentioned the following (see exercise 4 at the end):

The first line might be tricky to get working. It’s helpful to know that # starts a comment in Bash, and ! has a special meaning even within double-quoted (") strings. Bash treats single-quoted strings (') differently: they will do the trick in this case. See the Bash quoting manual page for more information.

pomsky
  • 68,507

1 Answers1

4

TL;DR

I'd gess that the main objective of that excercise is for you to understand the importance of quoting the parameters passed to each command, so you should quote each line before passing it to echo:

echo '#!/bin/sh' > /tmp/missing
echo 'curl --head --silent https://missing.csail.mit.edu' >> /tmp/missing

Detailed explanation

As the suggestion to the problem explains, the main difficulty in there is adding the first line since it contains a #, a special character that tells bash to start a comment. In order to write that into the file you want, the more straightforward way to do it is to quote the whole line like this:

echo '#!/bin/sh' > /tmp/missing

You don't need to quote the second line because it does not contain any bash special character, no word of that line is a flag or option of echo and there are no consecutive spaces (which would be treated as a single one because each word would be treated as a parameter of echo). However, since the reasons for which you don't need to quote the line are quite fragile, it is a good practice to allways quote it and, in general, to quote the arguments to your commands unless you want each word of a line to be interpreted as an argument or you want bash to process something in any other way. Then, the second command you'd run is:

echo 'curl --head --silent https://missing.csail.mit.edu' >> /tmp/missing

Be aware, though, that for lines containing a ', you should not just surround the line with single quote since the first one would indicate the end of the quoted text. In this case, you may stop quoting before every single quote and also start quoting after every single quote and also escape or quote each single quote; that is, replacing the quote with \' or "'".

For instance, in order to echo a line don't just suround me with quotes, you may do the following:

echo 'don'\''t just suround me with quotes'

Taking into acount this considerations will help you pass the arguments you want to each command and you will avoid the most common bash bugs.

Alternative solution

If you don't take into consideration the requirement to write one line at a time, you may do the following:

cat <<'EOF' > /tmp/missing
#!/bin/sh
curl --head --silent https://missing.csail.mit.edu
EOF

In order to learn more about this idiom, you may refer to man bash or this other question on stackoverflow.

pLumo
  • 26,947