Realicé algunas búsquedas en línea, encontré simples 'tutoriales' para usar canalizaciones con nombre. Sin embargo, cuando hago algo con trabajos en segundo plano, parece que pierdo muchos datos.Usar canalizaciones con nombre con bash - Problema con pérdida de datos
[[Editar: encontró una solución mucho más simple, ver respuesta a la publicación. Entonces la pregunta que presento ahora es académica - en caso de que uno quiera un servidor de trabajo]]
Usando Ubuntu 10.04 con Linux 2.6.32-25-genérico # 45-Ubuntu SMP Sáb 16 Oct 19:52:42 UTC 2010 x86_64 GNU/Linux
GNU bash, versión 4.1.5 (1) - liberación (x86_64-pc-linux-gnu).
Mi función bash es:
function jqs
{
pipe=/tmp/__job_control_manager__
trap "rm -f $pipe; exit" EXIT SIGKILL
if [[ ! -p "$pipe" ]]; then
mkfifo "$pipe"
fi
while true
do
if read txt <"$pipe"
then
echo "$(date +'%Y'): new text is [[$txt]]"
if [[ "$txt" == 'quit' ]]
then
break
fi
fi
done
}
corro esto en el fondo:
> jqs&
[1] 5336
Y ahora que lo alimentan:
for i in 1 2 3 4 5 6 7 8
do
(echo aaa$i > /tmp/__job_control_manager__ && echo success$i &)
done
La salida es inconsistente. Con frecuencia no obtengo todos los ecos de éxito. Obtengo como máximo tantos ecos de texto nuevos como ecos de éxito, a veces menos.
Si elimino el '&' del 'feed', parece que funciona, pero estoy bloqueado hasta que se lea la salida. De ahí que quiera dejar que los subprocesos se bloqueen, pero no el proceso principal.
El objetivo es escribir una secuencia de comandos de control de trabajo simple para poder ejecutar un máximo de 10 trabajos en paralelo y poner el resto en cola para su posterior procesamiento, pero sé que se ejecutan.
gestor de trabajos completa a continuación:
function jq_manage
{
export __gn__="$1"
pipe=/tmp/__job_control_manager_"$__gn__"__
trap "rm -f $pipe" EXIT
trap "break" SIGKILL
if [[ ! -p "$pipe" ]]; then
mkfifo "$pipe"
fi
while true
do
date
jobs
if (($(jobs | egrep "Running.*echo '%#_Group_#%_$__gn__'" | wc -l) < $__jN__))
then
echo "Waiting for new job"
if read new_job <"$pipe"
then
echo "new job is [[$new_job]]"
if [[ "$new_job" == 'quit' ]]
then
break
fi
echo "In group $__gn__, starting job $new_job"
eval "(echo '%#_Group_#%_$__gn__' > /dev/null; $new_job) &"
fi
else
sleep 3
fi
done
}
function jq
{
# __gn__ = first parameter to this function, the job group name (the pool within which to allocate __jN__ jobs)
# __jN__ = second parameter to this function, the maximum of job numbers to run concurrently
export __gn__="$1"
shift
export __jN__="$1"
shift
export __jq__=$(jobs | egrep "Running.*echo '%#_GroupQueue_#%_$__gn__'" | wc -l)
if (($__jq__ '<' 1))
then
eval "(echo '%#_GroupQueue_#%_$__gn__' > /dev/null; jq_manage $__gn__) &"
fi
pipe=/tmp/__job_control_manager_"$__gn__"__
echo [email protected] >$pipe
}
Calling
jq <name> <max processes> <command>
jq abc 2 sleep 20
se iniciará un proceso. Esa parte funciona bien. Comienza un segundo, bien. Uno por uno a mano parece funcionar bien. Pero comenzar 10 en un bucle parece perder el sistema, como en el ejemplo más simple anterior.
Cualquier sugerencia sobre lo que puedo hacer para resolver esta aparente pérdida de datos IPC sería muy apreciada.
Saludos, Alain.
Eche un vistazo en [segundo 2018 Edit to * Cómo configurar una variable a la salida de un comando *] (https://stackoverflow.com/a/41236640/1765658) o en [GitHub.com: Connector- bash] (https://github.com/F-Hauri/Connector-bash). Donde conecto * subprocess hoding * tools * a mi sesión de shell actual. –