¿Hay alguna manera de reescribir la estructura de comandos A && B || C | Dpara que B o C se canalicen a D?
Con el comando actual solo se ejecutan B o C y D.
Por ejemplo:
¿Hay alguna manera de reescribir la estructura de comandos A && B || C | Dpara que B o C se canalicen a D?
Con el comando actual solo se ejecutan B o C y D.
Por ejemplo:
Respuestas:
Sí, en bash puedes usar paréntesis:
(A && B || C) | D
De esta manera, la salida de A && B || Cse canalizará a D.
sh:)
Aestá dentro del subshell, esto también incluye A).
Puedes escribir esto como
if A; then B; else C; fi | D
Dices que quieres ejecutar cualquiera Bo C, pero A && B || Cno lo logras. Si Atiene éxito, pero se Bejecuta y falla, se ejecutará C.
Nota 1: si de alguna manera puede garantizar que Bsiempre tenga éxito y quiera seguir con una versión corta, entonces aún optaría por
{ A && B || C; } | D
terminado ( ... ), ya que este último obliga innecesariamente a crear una nueva subshell, que puede optimizarse o no.
Nota 2: ambas formas asumen que Ano producen resultados, lo cual es cierto en su ejemplo, pero no necesariamente en general. Eso puede ser evitado por
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
{ … }no obliga a crear una subshell debido a la tubería? Observo el siguiente comportamiento: pgrep bashy pgrep bash | caty if true; then pgrep bash; fiy { pgrep bash; }tengo una línea de salida; ( pgrep bash; )y ( pgrep bash; ) | caty { pgrep bash; } | caty if true; then pgrep bash; fi | cattienen dos líneas de salida.
... | ...hace que se cree una subshell, eso es inevitable. ( ... ), al menos en teoría, hace que se cree un subshell adicional que { ...; }evita, pero eso es lo que quise decir con "puede o no optimizarse": es posible que en este caso particular, el shell se dé cuenta de que no importa, el El efecto sería el mismo.
La respuesta del aceptador es correcta pero no cubre el caso de uso potencial para no tener la salida de Acomo la entrada de D. Para lograrlo, necesitará una redirección de transmisión en Afunción de sus necesidades.
Si desea descartar la salida de Atodos modos:
{ A >/dev/null && B || C; } | DSi desea ver la salida de Aen el terminal:
{ A >/dev/tty && B || C; } | DSi necesita la salida de Acomo la entrada de un comando posterior E, necesitará un grupo de comando adicional y una redirección de flujo:
{ { A >&3 && B || C; } | D; } 3>&1 | ESi todo esto le parece demasiado arcano (como a mí), le recomiendo que use la variable de shell especial para el estado de salida Ay trabaje con eso:
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
Si quieres ser más conciso pero no demasiado arcano, te sugiero esto:
A; { [ $? -eq 0 ] && B || C; } | D
(Vea también la última parte de la respuesta de hvd que no noté cuando escribí mi respuesta original).
Ade la tubería.
A && (B || C) | D, si no desea que B, C o D se ejecuten cuando A falla