решение1
Да, в bash можно использовать скобки:
(A && B || C) | D
Таким образом, вывод A && B || C
будет передан в D
.
решение2
Вы можете написать это как
if A; then B; else C; fi | D
Вы говорите, что хотите запустить либо B
или C
, но A && B || C
не достигает этого. Если A
успешно, но B
запускается и терпит неудачу, то будет выполнено C
.
Примечание 1: если вы можете каким-то образом гарантировать, что это B
всегда сработает, и хотите придерживаться короткой версии, то я бы все равно выбрал
{ A && B || C; } | D
более ( ... )
, так как последнее приводит к ненужному созданию новой подоболочки, которая может быть оптимизирована или нет.
Примечание 2: обе формы A
не производят вывода, что верно в вашем примере, но не обязательно так в общем случае. Этого можно избежать,
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
решение3
Ответ акцептора правильный, но он не охватывает потенциальный вариант использованиянетиметь выход A
в качестве входа D
. Чтобы добиться этого, вам понадобится перенаправление потока в A
зависимости от ваших потребностей.
Если вы все равно хотите отменить вывод
A
:{ A >/dev/null && B || C; } | D
Если вы хотите увидеть вывод
A
на терминале:{ A >/dev/tty && B || C; } | D
Если вам нужны выходные данные
A
в качестве входных данных для последующей команды,E
вам понадобится дополнительная группа команд и перенаправление потока:{ { A >&3 && B || C; } | D; } 3>&1 | E
Если все это кажется вам слишком заумным (как и мне), я рекомендую вам использовать специальную переменную оболочки для статуса выхода A
и работать с ней:
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
Если вы хотите быть более кратким, но не слишком заумным, я предлагаю следующее:
A; { [ $? -eq 0 ] && B || C; } | D
(См. также последнюю частьответ hvd(Чего я не заметил, когда писал свой первоначальный ответ.)