scripts script programacion pasar parametros manejo español ejemplos comandos cadenas bash shell file-descriptor

bash - script - shell linux ejemplos



¿Cómo redirigir un descriptor de archivo de salida de una subshell a un descriptor de archivo de entrada en el shell primario? (2)

(En BASH) Quiero que una subshell use un descriptor de archivo no STDOUT que no sea STDERR para pasar algunos datos al shell primario. ¿Cómo puedo hacer eso? Eventualmente me gustaría guardar los datos en alguna variable del shell padre.

( # The following two lines show the behavior of the subshell. # We cannot change them. echo "This should go to STDOUT" echo "This is the data I want to pass to the parent shell" >&3 ) #... data_from_subshell=... # Somehow assign the value of &3 of the # subshell to this variable

EDITAR: La subshell ejecuta un programa de caja negra que escribe en STDOUT y & 3.


La forma más fácil, por supuesto, es capturar el resultado directamente en el padre

data_from_subshell=$(echo "This is the data I want to pass to the parent shell")

Puede usar un conducto con nombre como una forma alternativa de leer datos de un niño

mkfifo /tmp/fifo

ahora puedes redirigir al niño a /tmp/fifo

( echo "This should go to STDOUT" echo "This is the data I want to pass to the parent shell" >/tmp/fifo ) &

y el padre puede leer desde allí

read data_from_subshell </tmp/fifo

Otra forma es usar coproc para iniciar un proceso secundario. Esto crea un elemento secundario con una tubería bidireccional y redirige los datos stdin y stdout del elemento secundario a los descriptores de las tuberías. Para usar tanto el conducto como el stdout en el elemento secundario, primero debe duplicar la salida estándar en el elemento primario

exec 4>&1 # duplicate stdout for usage in client coproc SUBSHELL ( exec 3>&1 1>&4- # redirect fd 3 to pipe, redirect fd 1 to stdout ( echo "This should go to STDOUT" echo "This is the data I want to pass to the parent shell" >&3 ) ) exec 4>&- # close fd 4 in parent read data <&${SUBSHELL[0]} echo "Parent: $data"

Coprocesos se introdujeron en Bash 4.0.


CUIDADO, BASHISM AHEAD (hay depósitos posix que son significativamente más rápidos que bash, p. Ej. Ceniza o guión, que no tienen sustitución de proceso).

Puede hacer un cambio de dirección para mover la salida estándar original a un nuevo descriptor para que la salida estándar esté disponible para la tubería (desde lo alto de mi cabeza):

exec 3>&1 # creates 3 as alias for 1 run_in_subshell() { # just shortcut for the two cases below echo "This goes to STDOUT" >&3 echo "And this goes to THE OTHER FUNCTION" }

Ahora deberías poder escribir:

while read line; do process $line done < <(run_in_subshell)

pero la construcción <() es un bashismo. Puedes reemplazarlo por tubería

run_in_subshell | while read line; do process $line done

excepto que el segundo comando también se ejecuta en subshell , porque todos los comandos en pipeline lo hacen.