Tengo una serie de procesos iniciados a través de un script bash, escuchando y reproduciendo, a través de netcat, transmisiones de audio que llegan a puertos separados:
#!/bin/bash
# listener.sh
while :
do
nc -l 900$1 | aplay -
sleep 1
done
exit 0
Este script se inicia en otro script con argumentos para definir puertos únicos. p.ej.
#!/bin/bash
# startlisterners.sh
if [ ! -f /tmp/listener1.pid ]; then
nohup listener.sh 1 &
echo $! > /tmp/listener1.pid
fi
if [ ! -f /tmp/listener2.pid ]; then
nohup listener.sh 2 &
echo $! > /tmp/listener2.pid
fi
..... etc.
exit 0
Necesito, periódicamente, poder eliminar selectivamente instancias de "aplay" en los subíndices mientras mantengo los subíndices en ejecución.
¿Cómo puedo acceder a los PID individuales de cada proceso de reproducción?
Respuesta1
En lugar de
nc -l 900$1 | aplay -
sleep 1
correr
nc -l "900$1" | aplay - &
# here you can use $!
wait
sleep 1
Ahora, donde dice, # here you can use $!
puede, por ejemplo, escribir $!
en un archivo predefinido. Este enfoque puede requerir listener.sh
conocer su número ( listener1
, listener2
etc.) para poder usar un archivo con el número correcto.
Otra forma es definir una trampa antes while
en listener.sh
:
trap 'kill "$!"' SIGUSR2
Con esto implementado, si envía SIGUSR2
( kill -s SIGUSR2 …
) a un listener.sh
proceso, será kill
el suyo aplay
. Ya conoces los PID de tus oyentes gracias a /tmp/listener*.pid
los archivos.
importa lo queel manualdice:
Si Bash está esperando a que se complete un comando y recibe una señal para la cual se ha configurado una trampa, la trampa no se ejecutará hasta que se complete el comando. Cuando Bash está esperando un comando asincrónico a través del
wait
incorporado, la recepción de una señal para la cual se ha configurado una trampa hará que elwait
incorporado regrese inmediatamente con un estado de salida mayor que128
, inmediatamente después de lo cual se ejecuta la trampa.
Esto significa que debes ejecutarlo aplay
en segundo plano wait
(como arriba).
Solo puedo suponer que ejecuta varios oyentes para poder atender a varios clientes (aún como máximo un cliente por puerto en un momento dado). Entonces, ocasionalmente necesitarás matar aplay
, por ejemplo, cuando un cliente desaparece silenciosamente y nc
no recibe notificación.
Tal vez estocompletoEl enfoque puede ser reemplazado por uno único socat
:
socat TCP-LISTEN:9001,fork EXEC:'aplay -'
Gracias a fork
ello puede atender a múltiples clientes en el mismo puerto. Utilice la -T
opción (ver man 1 socat
) para finalizar conexiones obsoletas. Incluso sin -T
ellos deberíantiempo de espera eventualmentede todos modos. Sin embargo, la solución es vulnerable a un ataque de DOS.