0

From a Markdown style guide by Google:

Because most commandline snippets are intended to be copied and pasted directly into a terminal, it's best practice to escape any newlines. Use a single backslash at the end of the line:

bazel run :target -- --flag --foo=longlonglonglonglongvalue \
--bar=anotherlonglonglonglonglonglonglonglonglonglongvalue

Could someone explain why escaping newlines in the following snippet makes it work wrong if I copy-and-paste it into a terminal (I use zsh on a Mac, not sure the same issue happens in pure Bash and/or in other terminals. Does it?):

If you copy-and-paste this snippet into a terminal, it works fine:

for (( counter=10; counter>0; counter-- ))
do
echo -n "$counter "
done
printf "\n"

But if you copy-and-paste this one, there will be an error:

for (( counter=10; counter>0; counter-- )) \
do \
echo -n "$counter " \
done \
printf "\n"

3 Answers 3

2

Newline (NL, ^J) marks End-Of Line, and usually ends a command.

Escaped NL characters are treated as a blank, and don't end commands, or lines.

foo
bar

are two commands.

foo \
bar

is one command,

foo bar
1
  • no, escaped newlines disappear completely, they're not replaced by a blank. foo \<nl>bar is the same as foo bar because you had a space there just before the backslash
    – ilkkachu
    Commented Jul 6, 2023 at 17:20
2

\ followed by a newline is a line-continuation, it's used to break very long lines into more than one generally for legibility.

The shell upon reading them, just removes them:

ec\
ho t\
est

Is just another way to write:

echo test

And:

for (( counter=10; counter>0; counter-- )) \
do \
echo -n "$counter " \
done \
printf "\n"

Is another way to write:

for (( counter=10; counter>0; counter-- )) do echo -n "$counter " done printf "\n"

Which would run echo -n "$counter " done printf "\n" in a loop, except it's missing the done to close the loop (the other done is just an argument to echo).

So you may want to insert some \<newline> to break very long lines, but you don't want to replace <newline>s (which are used to delimit commands among other things) with \<newline> which is the same as nothing¹.


¹ except inside single quotes (or $'...' for those shells that support that) or here-documents with quoted delimiters (as in << "EOF"...EOF)

1

In shell syntax, there is a semicolon (;) token which separates commands.

As an alternative a newline can be used. In other words, you can do this:

command ; command

or this:

command
command

Certain syntactic constructs in the shell consist of multiple commands, like looping:

while test-command1; test-comand2 ; do command1; command2; command3; done

Syntactically, this is six commands: a while command which marks the start of a sequence of test commands which control the loop. Then a do command which marks the start of the loop body. Finally a done command that marks the end.

When this is written on multiple lines, the semicolons become optional:

while test-command-1
      test-command-2
do    command1
      command2
      command3
done

Now the backslash-newline sequence, often called a line continuation, turns multiple physical lines into a single logical line. A similar line-continuation feature is found in the Awk language, in the Make language and in the preprocessing feature of the C language.

When we break a shell script into multiple physical lines with line continuations, the interpreter sees only a single line. Therefore, the semicolons are required.

Wrong:

while test-command-1 \
      test-command-2 \
do    command1 \
      command2 \
      command3 \
done

Right:

while test-command-1 ; \
      test-command-2 ; \
do    command1 ; \
      command2 ; \
      command3 ; \
done

It's very common to see this in in a Makefile. In Make, every line of a build recipe is a separate shell script run in a separate shell instance. Thus every script must fit into a single logical line of the make syntax. Line continuations are used to break complex shell scripts into multiple physical lines, and so the semicolons are required.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .