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.