He estado trabajando en esto durante un tiempo, y parece que no hay manera de hacer eso con la sustitución de proceso, excepto para recurrir a inline señalización, y que puede realmente se debe usar solo para los tubos de entrada, así que no voy a ampliarlo.
Sin embargo, bash-4.0 proporciona coprocesos que se pueden utilizar para reemplazar la sustitución de procesos en este contexto y proporcionar una cosecha limpia.
El siguiente fragmento de código proporcionado por usted:
git status --short | tee >(xargs -Istr test -z str)
puede ser reemplazado por algo parecido:
coproc GIT_XARGS { xargs -Istr test -z str; }
{ git status --short | tee; } >&${GIT_XARGS[1]}
exec {GIT_XARGS[1]}>&-
wait ${GIT_XARGS_PID}
Ahora, por alguna explicación:
La llamada coproc
crea un nuevo coproceso, llamándolo GIT_XARGS
(puede usar el nombre que desee) y ejecute el comando entre corchetes. Se crea un par de tuberías para el coproceso, redirigiendo su stdin y stdout.
La llamada coproc
establece dos variables:
${GIT_XARGS[@]}
que contiene tubos para procesar stdin y stdout, apropiadamente ([0]
para leer desde stdout, [1]
escribir en la entrada estándar),
${GIT_XARGS_PID}
que contienen el coproceso PID.
A continuación, se ejecuta su comando y su salida se dirige al segundo conducto (es decir, coprocesamiento 'stdin). La parte >&${GIT_XARGS[1]}
de aspecto críptico se expande a algo así como >&60
que es una redirección de salida a fd.
Tenga en cuenta que necesitaba poner su comando entre llaves. Esto se debe a que una interconexión hace que se generen subprocesos y no heredan los descriptores de archivos del proceso principal. En otras palabras, lo siguiente:
git status --short | tee >&${GIT_XARGS[1]}
podría dar error descriptor de archivo no válido, ya que existe el fd relevante en proceso padre y no el proceso tee
generado. Ponerlo entre llaves hace que bash aplique la redirección a toda la tubería.
La llamada exec
se utiliza para cerrar el conducto a su coproceso. Cuando utilizó la sustitución de procesos, el proceso se generó como parte de la redirección de salida y el conducto se cerró inmediatamente después de que la redirección ya no tuviera efecto. Dado que la vida útil de la tubería de coprocesamiento se extiende más allá de una sola redirección, debemos cerrarla explícitamente.
El cierre de la tubería de salida debe hacer que el proceso obtenga la condición EOF en stdin y termine con elegancia. Usamos wait
para esperar su finalización y cosecharlo. wait
devuelve el estado de salida del coproceso.
Como última nota, tenga en cuenta que en este caso, no puede usar kill
para finalizar el proceso, ya que eso alteraría su estado de salida.
Disculpe, pero ¿qué es exactamente lo que quiere lograr? ¿Simplemente comprobando si hay estado de git en ese directorio? –
Sí, es parte de una secuencia de comandos de implementación y debe salir de cero si el directorio está sucio. – jodell