The short answer is that <
, >
, and their variants
have the highest binding precedence (tightest binding),
followed by |
, followed by &&
and ||
, followed by ;
and &
.
So, only the echo "Thumbnail creation failed"
is piped into the tee
.
A slightly longer answer would point out that the highest precedence is actually grouping, which can be indicated with parentheses or braces. For example,
A && (B; C)
and
A && { B; C;}
are approximately equivalent to
if A
then
B
C
fi
Notes:
- The parentheses give you a subshell;
i.e., commands
B
and C
run in a child process.
Therefore,
commands like variable assignments or cd
will have no effect on the parent shell.
Commands in braces run in the same process as the A
command.
Therefore, the brace construct A && { B; C;}
is closer to the if
-then
-else
construct.
- In the brace syntax,
there must be a space after the
{
and a ;
(or a &
, or newline) before the }
.
For further reading, see What are the shell’s control and redirection operators? and When is ‘if’ not necessary? (particularly my answers).
For even more further reading, see the bash(1) man page and
the POSIX specification / definition of the Shell Command Language,
specifically Section 2.9, Shell Commands
and Section 2.10.2, Shell Grammar Rules.
This is an attempt to provide some context for the above:
- Things like
myVar=42
IFS= read a
date
cd /some/directory
ls -laR dir1 dir2
cat foo* > /tmp/allfoo
ls -laR dir{1,2}
find . -type f -name "foo*" -print > /tmp/output 2> /dev/null
> newfile
[ -f catfood ]
exit
are all considered to be “simple commands”.
are “pipelines”.
The grammar establishes building blocks and builds on them,
as is typical for formal grammars like this
(and for programming languages like C),
so an individual “simple command” is considered to be a “pipeline”,
even though it doesn’t contain a pipe.
It doesn’t make (semantic) sense
for a variable assignment to be a component of a pipeline,
but things like
x=1 | od -ab
or
ls -laR | z=0
are syntactically valid.
Things likepipeline1 && pipeline2 || pipeline3
are called “lists” by bash and “AND-OR lists” by POSIX.
Again, an individual “pipeline” or even an individual “simple command”
is considered to be an “AND-OR list”,
even though it doesn’t contain an AND or an OR.
When you get to things likeAND-OR list1 & AND-OR list2 ; AND-OR list3
the nomenclature starts to get a bit inconsistent.
Bash calls these “lists” also;
POSIX calls them “lists”, “compound lists” and (rarely) “terms”.
Again, an individual “AND-OR list”, “pipeline”
or even an individual “simple command” is considered to be a “list”,
even though it doesn’t contain a &
or a ;
.
Things like(compound_list)
and
{ compound_list;}
and the flow-control commands
(`for`, `if`-`then`-`else`, `while`, etc.) are called “compound commands”.
In the examples above, it probably makes the most sense
to interpret A
, B
, and C
to be pipelines.
Remember, a “pipeline” can be an individual “simple command”;
it doesn’t need to contain a pipe.
{
...}
should work. I might have tried it unsystematically and not got the expected results. – Sridhar Sarnobat Oct 22 '14 at 00:27