2011-09-28 25 views
6

me gustaría convertir el siguiente:proceso de sustitución Bash y salida códigos

git status --short && (git status --short | xargs -Istr test -z str)

que me obtiene el resultado deseado de la duplicación de la salida a la salida estándar y hacer una verificación de longitud cero en el resultado en algo más cerca de:

git status --short | tee >(xargs -Istr test -z str)

que, desgraciadamente, devuelve el código de salida de la T (siempre cero).

¿Hay alguna forma de obtener elegantemente el código de salida del proceso sustituido?

[EDIT]

voy con la siguiente por ahora, impide ejecutar el mismo comando dos veces, pero parece pedir algo mejor:

OUT=$(git status --short) && echo "${OUT}" && test -z "${OUT}"

+0

Disculpe, pero ¿qué es exactamente lo que quiere lograr? ¿Simplemente comprobando si hay estado de git en ese directorio? –

+0

Sí, es parte de una secuencia de comandos de implementación y debe salir de cero si el directorio está sucio. – jodell

Respuesta

5

Mira aquí:

 
    $ echo xxx | tee >(xargs test -n); echo $? 
xxx 
0 
    $ echo xxx | tee >(xargs test -z); echo $? 
xxx 
0 

y buscar aquí:

 
    $echo xxx | tee >(xargs test -z; echo "${PIPESTATUS[*]}") 
xxx 
123 
    $echo xxx | tee >(xargs test -n; echo "${PIPESTATUS[*]}") 
xxx 
0 

Eso es?

Ver también Pipe status after command substitution

+0

No sabía nada sobre PIPESTATUS, fue útil, gracias. – jodell

+4

En caso de que alguien más venga y piense que PIPESTATUS resuelve esto, no es así. Si el eco $? se mueve dentro del constructo> (...), también se comporta como se esperaba. Si la versión PIPESTATUS se mueve fuera, devuelve 0 en ambos casos también. La camiseta –

0
#!/bin/bash 
if read q < <(git status -s) 
then 
    echo $q 
    exit 
fi 
2

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:

  1. ${GIT_XARGS[@]} que contiene tubos para procesar stdin y stdout, apropiadamente ([0] para leer desde stdout, [1] escribir en la entrada estándar),
  2. ${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.

+0

no sirve para nada, la red stdout se redirecciona a stdout. – weynhamz

+0

'exec {GIT_XARGS [1]}> & -' returns '-bash: exec: {GIT_XARGS [1]}: no encontrado' para mí. –

+0

¿Tiene bash-4.0 o más reciente? –

Cuestiones relacionadas