Esiste un modo per riscrivere la struttura dei comandi in A && B || C | Dmodo che B o C sia reindirizzato in D?
Con il comando corrente vengono eseguiti solo B o entrambi C e D.
Per esempio:
Esiste un modo per riscrivere la struttura dei comandi in A && B || C | Dmodo che B o C sia reindirizzato in D?
Con il comando corrente vengono eseguiti solo B o entrambi C e D.
Per esempio:
Risposte:
Sì, in bash puoi usare le parentesi:
(A && B || C) | D
In questo modo l'output di A && B || Cverrà reindirizzato D.
sh:)
Aè all'interno della subshell, anche questo include A.)
Puoi scrivere questo come
if A; then B; else C; fi | D
Dici di voler correre Bo C, ma A && B || Cnon ci riesci. Se Ariesce, ma Bfunziona e fallisce, verrebbe eseguito C.
Nota 1: se in qualche modo riesci a garantire che abbia Bsempre successo e vuoi restare con una versione breve, allora opterei comunque
{ A && B || C; } | D
finita ( ... ), poiché quest'ultima impone inutilmente la creazione di una nuova subshell, che può o meno essere ottimizzata.
Nota 2: entrambe le forme presuppongono che Anon produca alcun output, il che è vero nel tuo esempio ma non necessariamente in generale. Questo può essere evitato da
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
{ … }non imponga la creazione di una subshell a causa della pipe? Osservo il seguente comportamento: pgrep bashe pgrep bash | cated if true; then pgrep bash; fie { pgrep bash; }ho una linea di output; ( pgrep bash; )e ( pgrep bash; ) | cate { pgrep bash; } | cate if true; then pgrep bash; fi | cathanno due linee di output.
... | ...provoca la creazione di una subshell, il che è inevitabile. ( ... ), almeno in teoria, provoca la creazione di una sottostruttura aggiuntiva che { ...; }evita, ma è quello che intendevo con "può o non può essere ottimizzato": è possibile che in questo caso particolare, la shell capisca che non ha importanza, il l'effetto sarebbe lo stesso.
La risposta dell'accettatore è corretta ma non copre il potenziale caso d'uso per non avere l'output di Acome input di D. Per ottenere ciò, avrai bisogno di un reindirizzamento dello stream in Abase alle tue esigenze.
Se si desidera eliminare Acomunque l'output di :
{ A >/dev/null && B || C; } | DSe vuoi vedere l'output di Asul terminale:
{ A >/dev/tty && B || C; } | DSe è necessario l'output di Acome input di un comando successivo, Eè necessario un gruppo di comandi aggiuntivo e il reindirizzamento dello stream:
{ { A >&3 && B || C; } | D; } 3>&1 | ESe tutto ciò ti sembra troppo arcano (come per me) ti consiglio di usare la speciale variabile shell per lo stato di uscita Ae lavorare con quello:
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
Se vuoi essere più conciso ma non troppo arcano, suggerisco questo:
A; { [ $? -eq 0 ] && B || C; } | D
(Vedi anche l'ultima parte della risposta di hvd che non ho notato quando ho scritto la mia risposta originale.)
Adalla pipeline.
A && (B || C) | D, se non vuoi che B, C o D