Why are there backslash `\` line breaks on this apt install command?
The backslash is used by bash to indicate a line continuation and is commonly used in bash scripts. However, the backslash is actually the bash escape character. So this use of the backslash 'escapes' the the \newline to create a continuation. Cool, and good to know, eh? In particular, Section 3.1.2.1 of the GNU bash manual says:
A non-quoted backslash ‘\’ is the Bash escape character. It preserves the literal value of the next character that follows, with the exception of newline. If a \newline pair appears, and the backslash itself is not quoted, the \newline is treated as a line continuation (that is, it is removed from the input stream and effectively ignored).
To answer your specific question: the author is simply indicating that the multi-line expression is a single-line bash command. This multi-line expression will work if there are no characters after the '\' but \newline. However, if one cuts and pastes, there may be all sorts of cruft (e.g. spaces) after the '\'. So, either remove all trailing characters after the '\' or simply put the command on one line, as you have been doing. I often find using '\' convenient when typing a long command, but it's a matter of personal preference.
The \
character at the end of the line is interpreted as a line continuation character in bash that tells bash to expect a continuation of the command on the next line unless:
- the
\
character is part of a string that is enclosed by single or double quote characters - or the
\
character is escaped by putting another backslash character in front of it like this\\
which makes it interpreted as a literal character.
Note: A non-quoted backslash \
is also used as an escape character in bash.
Copying/pasting a multiple line command like the below example from a text editor into the terminal results in the command being executed as a single line command.
Original text:
touch 1 \
2 \
3 \
&& ls
Original text copy/pasted into the terminal:
$ touch 1 \ > 2 \ > 3 \ > && ls 1 2 3
When the next multiple line command is copy/pasted from a text editor into the terminal, it results in the backslash characters being printed. The backslashes are interpreted as literal backslash characters in this command because they are enclosed in a pair of (single) quote characters.
Original text:
echo 'This is \
a multiple line \
command.'
In the terminal:
$ echo 'This is \ > a multiple line \ > command.' This is \ a multiple line \ command.
All the commands in this answer were originally typed by me in a text editor before pasting them into the terminal, so there are no invisible characters in the commands that could cause the commands to not work.
\
is the line-continuation character in sh
/ bash
just like in C (for #defining a long macro) or several other computer languages, allowing wrapping long lines in the source without changing the meaning in a line-oriented language.
It Just Works with a single paste if the selection doesn't include any spaces after the \
characters, only a newline. (In Chromium, that shows up as one blue character "box" that looks like a space at the end of the line, but apparently that's actually the newline.) Some web pages include trailing spaces in their formatted code. Perhaps the author copy/pasted from a terminal including spaces out to a fixed width and didn't clean it up for their code block.
You can tell this visually by selecting the whole thing and looking at the line endings. If it's good, you can just paste into a terminal. If not, you can paste into an editor and collapse the \ ... spaces newline
yourself.
Or if it's not too complicated, you may be able to paste inside single quotes on the command line and then use up-arrow to fix it.
Or paste each line separately if that will be easier for you, leaving out the \...
creating one long line. Or even manually include the \
but not trailing spaces or newline in your copy, then hit return after pasting each line.
Chromium at least allows you to adjust your selection with shift+left/right arrow if you're having trouble getting all the chars you want with the mouse but not chars you don't want.
Stack Exchange code formatting blocks can faithfully reproduce both good and bad examples so you can give it a try in your browser to see what to look for.
# Good:
echo 1 \
2 \
3
# Bad: spaces after backslash: needs editing to copy/paste
echo 1 \
2 \
3
paste result: the \
only escapes a space, not a newline. The individual lines are each harmless on their own, so it's safe to play around with. Not like a rm *
that's supposed to be part of something else, or starting any real programs, unless you have aliases or shell functions called 2
or 3`.
peter@volta:/tmp$ echo 1 \
1
peter@volta:/tmp$ 2 \
bash: 2: command not found
peter@volta:/tmp$ 3
bash: 3: command not found
One quick way to fix without starting up a separate editor:
Paste inside single quotes:
$ 'echo 1 \
> 2 \
> 3 '
bash: $'echo 1 \\ \n 2 \\ \n 3 ': command not found
Note that bash used $'C-escaped'
syntax to quote the command back to me. I did actually hit return to get the whole thing into command-line history. Bash line-editing won't go back to a previous already-submitted line, but multi-line quoted things do create a single multi-line history entry.
Up-arrow from there gives me all of that as a single command with embedded newlines that you can edit. You need to remove those or it will still be interpreted as multiple commands, like if they were ;
semicolons. Also of course remove the '
quotes.
Ctrl-w (unix-word-rubout) treats \
as a "word", and stops after it. (Unlike M-d (escape-d) to delete forward word, or M-backspace (delete backwards word); those would delete the word past the backslash). Ctrl-w even treats newline as a "word" (which is actually not what we want; from the first non-whitespace character we'd like to just kill to the \
on the previous line).
ctrl-left (or escape-f) / ctrl-right (or escape-b) move the cursor by whole words so you can quickly get to the start of a "line" for control-w. Or ctrl-r to reverse i-search for \
can get you there, then ctrl-right + left to get to the first word of the next line.
Ctrl-/ is undo, which is really handy because it lets you be aggressive with key-repeat or whatever, and quickly recover from overshoot.
If you use bash / readline line-editing regularly, you'll already remember many of these commands. I mention them here only for the benefit of people with less experience with bash line-editing who might think it was worth copy/pasting into an editor and then into bash. That's certainly an option, especially if you have an editor already open.
Another possibly useful editing command is M-\ (meta/escape backslash). That removes whitespace surrounding the cursor. You could just use that twice, with the cursor after the \
on the, to leave it as a multi-line thing with \
continuations. For example, recall the command with up-arrow
- backspace / ctrl-a / delete (or ctrl-d) to remove the single quotes
- ctrl-s forward i-search for
\
, then right arrow (or ctrl-f) to move the cursor onto the space after the\
- escape-
\
. (Or alt-\
if your terminal is properly set up for that to work as emacs line editing meta-, normally by sending an escape prefix.) - ctrl-s ctrl-s to forward i-search for the same thing again
- repeat the right arrow + kill whitespace
(I'm not suggesting memorizing these steps, this is just one way of using line-editing to get the job done.)
Or you can remove the \
and newline (and collapse whitespace down to 1 space if you want), like I suggested with control-w. Delete / ctrl-d or backspace will remove a newline or backslash when you have the cursor in the right place. Bash line-editing apparently doesn't have emacs M-space
to collapse whitespace to 1 (instead of 0) spaces, but you can do that manually with M-\
+ space.