¿Hay alguna manera de reescribir la estructura de comandos A && B || C | D
para 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 | D
para 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 || C
se canalizará a D
.
sh
:)
A
está 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 B
o C
, pero A && B || C
no lo logras. Si A
tiene éxito, pero se B
ejecuta y falla, se ejecutará C
.
Nota 1: si de alguna manera puede garantizar que B
siempre 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 A
no 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 bash
y pgrep bash | cat
y if true; then pgrep bash; fi
y { pgrep bash; }
tengo una línea de salida; ( pgrep bash; )
y ( pgrep bash; ) | cat
y { pgrep bash; } | cat
y if true; then pgrep bash; fi | cat
tienen 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 A
como la entrada de D
. Para lograrlo, necesitará una redirección de transmisión en A
función de sus necesidades.
Si desea descartar la salida de A
todos modos:
{ A >/dev/null && B || C; } | D
Si desea ver la salida de A
en el terminal:
{ A >/dev/tty && B || C; } | D
Si necesita la salida de A
como 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 | E
Si todo esto le parece demasiado arcano (como a mí), le recomiendo que use la variable de shell especial para el estado de salida A
y 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).
A
de la tubería.
A && (B || C) | D
, si no desea que B, C o D se ejecuten cuando A falla