Pid do processo em loop iniciado pelo script

Pid do processo em loop iniciado pelo script

Tenho vários processos iniciados por meio de um script bash, ouvindo e reproduzindo, via netcat, fluxos de áudio que chegam em portas separadas:

#!/bin/bash
# listener.sh

while :
do
    nc -l 900$1 | aplay - 
    sleep 1
done

exit 0

Este script é lançado em outro script com argumentos para definir portas exclusivas. por exemplo.

    #!/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

Preciso, periodicamente, ser capaz de eliminar seletivamente instâncias de "aplay" nos subscritos, enquanto mantenho os próprios subscritos em execução.

Como posso acessar os PIDs individuais de cada processo aplay?

Responder1

Em vez de

nc -l 900$1 | aplay - 
sleep 1

correr

nc -l "900$1" | aplay - &
   # here you can use $!
wait
sleep 1

Agora, onde ele lê, # here you can use $!você pode, por exemplo, gravar $!em um arquivo predefinido. Essa abordagem pode exigir listener.sho conhecimento de seu número ( listener1, listener2etc.) para poder usar um arquivo com o número correto.


Outra maneira é definir uma armadilha antes whileem listener.sh:

trap 'kill "$!"' SIGUSR2

Com isso implementado, se você enviar SIGUSR2( kill -s SIGUSR2 …) para um listener.shprocesso, ele será killseu aplay. Você já conhece os PIDs dos seus ouvintes graças aos /tmp/listener*.pidarquivos.

Cuidado com o queo manualdiz:

Se o Bash estiver aguardando a conclusão de um comando e receber um sinal para o qual uma armadilha foi definida, a armadilha não será executada até que o comando seja concluído. Quando o Bash está aguardando um comando assíncrono através do waitbuiltin, a recepção de um sinal para o qual uma armadilha foi definida fará com que o waitbuiltin retorne imediatamente com um status de saída maior que 128, imediatamente após o qual a armadilha é executada.

Isso significa que você deve executar aplayem segundo plano e waitpara isso (como acima).


Só posso supor que você execute vários ouvintes para poder atender vários clientes (ainda no máximo um cliente por porta a qualquer momento). Então você ocasionalmente precisa kill aplay, por exemplo, quando um cliente desaparece silenciosamente e ncnão é notificado.

Talvez istointeiroabordagem pode ser substituída por uma única socat:

socat TCP-LISTEN:9001,fork EXEC:'aplay -'

Graças a forkele pode atender vários clientes na mesma porta. Use a -Topção (consulte man 1 socat) para encerrar conexões obsoletas. Mesmo sem -Teles deveriamtempo limite eventualmentede qualquer forma. A solução é vulnerável a um ataque DOS.

informação relacionada