bash ubuntu tee process-substitution

bash: capturar stdout a una variable pero aún mostrarla en la consola



ubuntu tee (4)

Tengo un script bash que llama a varios procesos de larga ejecución. Quiero capturar el resultado de esas llamadas en variables por razones de procesamiento. Sin embargo, debido a que estos son procesos de larga ejecución, me gustaría que la salida de las llamadas rsync se muestre en la consola en tiempo real y no después del hecho.

Con este fin, he found una manera de hacerlo, pero se basa en la salida del texto a / dev / stderr. Siento que sacar a / dev / stderr no es una buena forma de hacer las cosas.

VAR1=$(for i in {1..5}; do sleep 1; echo $i; done | tee /dev/stderr) VAR2=$(rsync -r -t --out-format=''%n%L'' --delete -s /path/source1/ /path/target1 | tee /dev/stderr) VAR3=$(rsync -r -t --out-format=''%n%L'' --delete -s /path/source2/ /path/target2 | tee /dev/stderr)

En el ejemplo anterior, estoy llamando a rsync varias veces y quiero ver los nombres de los archivos a medida que se procesan, pero al final todavía quiero el resultado en una variable porque lo analizaré más tarde.

¿Hay una manera "más limpia" de lograr esto?

Si hace una diferencia, estoy usando Ubuntu 12.04, bash 4.2.24.


Aquí hay un ejemplo que captura tanto stderr como el código de salida del comando. Esto se basa en la respuesta de Russell Davis.

exec 5>&1 FF=$(ls /taco/ 2>&1 |tee /dev/fd/5; exit ${PIPESTATUS[0]}) exit_code=$? echo "$FF" echo "Exit Code: $exit_code"

Si la carpeta /taco/ existe, esto capturará su contenido. Si la carpeta no existe, capturará un mensaje de error y el código de salida será 2.

Si omite 2>&1 , solo se capturará stdout .


Duplique y 1 en su shell (en mi ejemplo a 5) y use & 5 en la subcadena (para que escriba en stdout (& 1) del shell primario):

exec 5>&1 FF=$(echo aaa|tee >(cat - >&5)) echo $FF

Se imprimirá aaa dos veces, unas por el eco en la subcamada, y la segunda vez se imprimirá el valor de la variable.

En tu código:

exec 5>&1 VAR1=$(for i in {1..5}; do sleep 1; echo $i; done | tee >(cat - >&5)) # use the value of VAR1


La respuesta de Op De Cirkel tiene la idea correcta. Se puede simplificar aún más (evitando el uso del cat ):

exec 5>&1 FF=$(echo aaa|tee /dev/fd/5) echo $FF


Puede usar más de tres descriptores de archivo. Intenta aquí:

http://tldp.org/LDP/abs/html/io-redirection.html

"A cada archivo abierto se le asigna un descriptor de archivo. [2] Los descriptores de archivo para stdin, stdout y stderr son 0, 1 y 2, respectivamente. Para abrir archivos adicionales, quedan los descriptores 3 a 9. Algunas veces es útil asigne uno de estos descriptores de archivos adicionales a stdin, stdout o stderr como un enlace duplicado temporal ".

El punto es si vale la pena complicar el guión solo para lograr este resultado. En realidad, no está realmente mal, la forma en que lo haces.