Ho lavorato su questo per un po ', e sembra che non c'è modo di farlo con sostituzione di processo, ad eccezione di ricorrere a inline di segnalazione, e che può essere usato solo per le pipe di input, quindi non lo espanderò.
Tuttavia, bash-4.0 fornisce coprocessi che possono essere utilizzati per sostituire la sostituzione di processo in questo contesto e fornire un raccolto pulito.
il seguente frammento fornito da voi:
git status --short | tee >(xargs -Istr test -z str)
può essere sostituito da qualcosa di simile:
coproc GIT_XARGS { xargs -Istr test -z str; }
{ git status --short | tee; } >&${GIT_XARGS[1]}
exec {GIT_XARGS[1]}>&-
wait ${GIT_XARGS_PID}
Ora, per qualche spiegazione:
La chiamata coproc
crea un nuovo coprocesso, nominandolo GIT_XARGS
(puoi usare qualsiasi nome tu voglia), ed eseguendo il comando tra parentesi. Viene creata una coppia di pipe per la coprocessione, reindirizzando lo stdin e lo stdout.
La chiamata coproc
imposta due variabili:
${GIT_XARGS[@]}
contenente tubi per elaborare stdin e stdout, opportunamente ([0]
per leggere da stdout, [1]
scrivere a stdin),
${GIT_XARGS_PID}
contenenti il coprocesso PID.
Successivamente, il comando viene eseguito e la sua uscita è diretto verso il secondo condotto (cioè coprocesso stdin). La parte >&${GIT_XARGS[1]}
che appare in modo criptico viene espansa a qualcosa come >&60
che è il normale reindirizzamento da output a dia.
Si prega di notare che avevo bisogno di mettere il comando in parentesi graffe. Questo perché una pipeline genera i sottoprocessi e non eredita i descrittori di file dal processo padre. In altre parole, il seguente:
git status --short | tee >&${GIT_XARGS[1]}
avrebbero esito negativo con l'errore non valida descrittore di file, dal momento che il fd rilevante esiste nel processo genitore e non il generato tee
processo. Inserendolo in coppia, bash applica il reindirizzamento all'intera pipeline.
La chiamata exec
viene utilizzata per chiudere il tubo al coprocessore. Quando hai utilizzato la sostituzione di processo, il processo è stato generato come parte del reindirizzamento dell'output e la pipe ad esso è stata chiusa immediatamente dopo che il reindirizzamento non ha avuto più effetto. Dal momento che la durata del coprocess 'pipe si estende oltre un singolo reindirizzamento, è necessario chiuderla in modo esplicito.
La chiusura del tubo di uscita dovrebbe causare il processo per ottenere la condizione EOF su stdin e terminare correttamente. Usiamo wait
per attendere la sua conclusione e raccoglierla. wait
restituisce lo stato di uscita della coprocessa.
Come nota finale, si noti che in questo caso non è possibile utilizzare kill
per interrompere la coprocessione poiché ciò ne modifica il suo stato di uscita.
Scusami, ma cosa vuoi raggiungere esattamente? Basta controllare se c'è stato git in quella directory? –
Sì, fa parte di uno script di distribuzione e dovrebbe uscire diverso da zero se la directory è sporca. – jodell