43

I have seen this construct in scripts a lot and used it myself, but it bothers me that I can't seem to find it in the documentation.

Example:

[ -f file1 ] &&
[ -f file2 ] &&
echo "Both files exist." ||
echo "One or the other file doesn't exist."

This could also be done with backslashes before the newlines, as mentioned in man bash:

If a \<newline> pair appears,  and  the  backslash  is  not
itself  quoted,  the \<newline> is treated as a line continuation (that
is, it is removed from the input stream and effectively ignored).

Example:

[ -f file1 ] && \
[ -f file2 ] && \
echo "Both files exist." || \
echo "One or the other file doesn't exist."

...but this doesn't seem to be necessary. The first version above works even without the backslashes.

Where can I find this in man bash? (Also, is this bash specific or POSIX compliant?)

Wildcard
  • 36,499

1 Answers1

52

A newline is ignored in a few contexts where there is manifestly an unterminated command. These contexts include after a control operator (&&, ||, |, &, ;, ;;, but not !).

I don't see this documented in the bash manual.

In POSIX, it's specified via the grammar rules. Wherever the rules have linebreak, you can have zero or more line breaks.

  • +1, I didn't knew it worked for the simple pipe ( | ) . I wish we could also put them on the next line, for readability, but it doesn't work that way (if doing that, you need to espace the preceding newline). – Olivier Dulac Jan 06 '16 at 12:49
  • 2
    @OlivierDulac How could that possibly work? When it's processing the current command line, how is it supposed to know that you're planning to type | at the beginning of the next line? Remember, the shell is also used interactively, not just in scripts, and the grammar is the same. – Barmar Jan 06 '16 at 19:43
  • @Barmar : I know, I do know this (wrote compilers at school ^^)... I said "I wish", and it is not a very plausible wish – Olivier Dulac Jan 06 '16 at 19:54
  • I wish bash supported an ellipsis (...) for line continuation. It would prevent a lot of logic bugs. But we can't have everything. – DocSalvager Jan 08 '16 at 10:11
  • 1
    @DocSalvager, can you give an example of a logic bug that would help prevent? I have a hard time seeing it.... – Wildcard Jan 09 '16 at 05:34
  • As you found, ending lines with && and || is not well documented and thus uncommon (except in your shop apparently). On seeing the example, my first thought was "syntax error". I've been writing shell script for decades and still had to look it up and run it to prove it is correct. Lines ending in '&' (run in background) are more common to me (and erroneous key repeats as well). Though this example works, using multiple && and || clauses is highly unreliable due to how they differ from the expected if-then logic. The epllipsis in english means "more to follow" so that makes more sense to me. – DocSalvager Jan 09 '16 at 06:58
  • 2
    @DocSalvager, I wouldn't actually use the code as I wrote it—it was an illustration. Without the last line (the else clause) I would use it that way, though. (For "if this and this then do that" this && this2 && that is fine but for an else clause I'd use an actual if then else fi.) – Wildcard Jan 13 '16 at 04:08
  • @Gilles: What do you mean by “A newline is ignored … after a control operator (…, &, ;, …).”? If I type foo &&, foo ||, or foo |, the shell prints a > prompt (PS2) and keeps on reading. (And, if I say one of those in a script, the shell reads the next line and appends it to the current one.  In both cases, it is the same behavior as if I typed a \ at the end of the line.) But if I type foo & or foo ;, the command is executed immediately. – G-Man Says 'Reinstate Monica' Aug 12 '16 at 05:59
  • @G-Man This thread was about scripts. An interactive shell executes a command as soon as it's read a syntactically valid command, so e.g. foo or foo & is executed immediately (because both are valid commands on their own) but foo && isn't (because there has to be a command after &&). – Gilles 'SO- stop being evil' Aug 12 '16 at 07:02
  • Might be worth noting that linebreak is treated as ; when part of compound command in {...} – Sergiy Kolodyazhnyy Feb 21 '18 at 01:55
  • @Sergiy Not just in {…}, anywhere in a compound command except I'm a few places where a ; would be invalid. And since the whole script is a compound command, that's anywhere except I'm those few places (and in quotes of course). That was the point of the question: why does it not happen sometimes? – Gilles 'SO- stop being evil' Feb 21 '18 at 07:43
  • Regarding @G-Man's comment, I too don't understand in what sense a newline is ignored after & (or ;). Thinking on it, I guess that's true in the strictly mathematical sense that a compiler author would see it, but taking into account common usage in shell scripts, it's clearer to say that a newline isn't required in those places. Right? (Which is just as true after && and | and ||, except it sounds funny to say a newline is "not required" when most people don't even realize a newline is an option at all in those places.) – Wildcard Jul 24 '18 at 01:04
  • @Wildcard Both statements are true, but the point of this thread was that newlines can be present after a control operator. Why would you distinguish between operators? That would only make things confusing since there is no difference. – Gilles 'SO- stop being evil' Jul 24 '18 at 04:12