Pipe B to D? - A && B || C | D
Yes, in bash you can use parentheses:
(A && B || C) | D
This way the output of A && B || C
will be piped into D
.
You can write this as
if A; then B; else C; fi | D
You say you want to run either B
or C
, but A && B || C
doesn't achieve that. If A
succeeds, but B
runs and fails, it would execute C
.
Note 1: if you can somehow guarantee that B
always succeeds and want to stick with a short version, then I'd still opt for
{ A && B || C; } | D
over ( ... )
, as the latter unnecessarily forces a new subshell to be created, which may or may not get optimised away.
Note 2: both forms assume A
produces no output, which is true in your example but not necessarily so in general. That can be avoided by
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
The accepter answer is correct but it doesn't cover the potential use case to not have the output of A
as the input of D
. To achieve that you’ll need a stream redirection on A
depending on your needs.
If you want to discard the output of
A
anyway:{ A >/dev/null && B || C; } | D
If you want to see the output of
A
on the terminal:{ A >/dev/tty && B || C; } | D
If you need the output of
A
as the input of a subsequent commandE
you’ll need an additional command group and stream redirection:{ { A >&3 && B || C; } | D; } 3>&1 | E
If all this looks too arcane to you (as it does to me) I recommend that you use the special shell variable for the exit status of A
and work with that:
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
If you want to be more concise but not too arcane I suggest this:
A; { [ $? -eq 0 ] && B || C; } | D
(See also the last part of hvd’s answer which I didn't notice when I wrote my original answer.)