13

When I'm reading tutorials that require the installation of many packages they'll often present a backslash \ at the end of the line?

sudo apt install gcc git pkg-config meson ninja-build \
                 libavcodec-dev libavformat-dev libavutil-dev \
                 libsdl2-dev

Why? When I copy paste the command into my Linux terminal it never works and I have to remove the backslashes and put everything on one line. What's going on?

5
  • 9
    As written, it should work - but the \ must be the very last character on the line (no trailing whitespace or non-printing characters). Maybe wherever you are copying the command from is adding trailing characters? – steeldriver Dec 31 '19 at 23:11
  • 4
    For additional discussion see Terminal shows > after entering \ – steeldriver Dec 31 '19 at 23:15
  • @steeldriver what do the \ slashes do in the command above? are they just telling the terminal that a line break is coming and to go to the next line? – Jason Hunter Dec 31 '19 at 23:59
  • 1
    I think it would be more correct to say they're telling the terminal to pass the line break to the shell as a literal part of the command string (where it is treated as a whitespace token separator), rather than treating it as a terminal control character. But my knowledge on the topic is limited. – steeldriver Jan 1 '20 at 0:16
  • 2
    @Jason Since Ubuntu uses BASH as the default shell, every new line means a new command or a line of code that is independent of the previous line. \ is an escape character. It tells bash to not to interpret new line character as such and interpret next line as the continuation of previous line. You can read the answers to the question steeldriver mentioned. (Coincidentally I'm one of the answerer there) – Kulfy Jan 1 '20 at 10:44
12

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.

19

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.

7

\ 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.

5
  • Imagine cd dir && \ (newline) rm -rf *... – S.S. Anne Jan 2 '20 at 20:33
  • @JL2210: Yup, that's a potential use-case for having a dangerous command at the start of a line. In that case I'd probably not paste it into a shell even if I thought the \+newline was going to work; if I'm wrong the consequences are really bad. – Peter Cordes Jan 3 '20 at 5:21
  • Check the Ctrl-w part. I think Ctrl-w even treats newline as a "word". is redundant. – S.S. Anne Jan 3 '20 at 12:12
  • @JL2210: It's maybe not relevant, but it's not redundant with anything else I said in the answer. It means I had to use it twice after getting the cursor to the right place, adding more steps of keypress -> look at screen -> think -> keypress. – Peter Cordes Jan 3 '20 at 12:15
  • Oh, yeah. I just woke up, though it said "backslash" or something. – S.S. Anne Jan 3 '20 at 12:17
1

When you are copying text from a webpage formatted like this:

sudo apt install gcc git pkg-config meson ninja-build \
         libavcodec-dev libavformat-dev libavutil-dev \
         libsdl2-dev

and it is not working then you have to copy it one line at a time and paste it into your terminal one line at a time. Copy each line to then end of the backslash (\) and no whitespace after it.

Alternatively you can copy all three lines into gedit or another editor, remove the \ and make a "one-liner" like this:

sudo apt install gcc git pkg-config meson ninja-build libavcodec-dev libavformat-dev libavutil-dev libsdl2-dev

then you can copy the one-liner from your editor and paste it into your terminal.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.