Pid процесса в цикле, запущенном скриптом

Pid процесса в цикле, запущенном скриптом

У меня есть несколько процессов, запущенных через bash-скрипт, которые прослушивают и воспроизводят через netcat аудиопотоки, поступающие на отдельные порты:

#!/bin/bash
# listener.sh

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

exit 0

Этот скрипт запускается в другом скрипте с аргументами для определения уникальных портов, например:

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

Мне периодически необходимо иметь возможность выборочно убивать экземпляры «aplay» в подскриптах, при этом сами подскрипты должны работать.

Как получить доступ к индивидуальным PID каждого процесса aplay?

решение1

Вместо

nc -l 900$1 | aplay - 
sleep 1

бегать

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

Теперь, когда он читает, # here you can use $!вы можете, например, записать $!в предопределенный файл. Этот подход может потребовать listener.shзнать его номер ( listener1и listener2т. д.), чтобы он мог использовать файл с правильным номером.


Другой способ — определить ловушку whileдо listener.sh:

trap 'kill "$!"' SIGUSR2

При такой реализации, если вы отправите SIGUSR2( kill -s SIGUSR2 …) процессу listener.sh, то он будет иметь killсвой собственный aplay. Вы уже знаете PID ваших слушателей благодаря /tmp/listener*.pidфайлам.

Имейте в виду, чторуководствоговорит:

Если Bash ожидает завершения команды и получает сигнал, для которого установлена ​​ловушка, ловушка не будет выполнена, пока команда не завершится. Когда Bash ожидает асинхронную команду через встроенную функцию wait, получение сигнала, для которого установлена ​​ловушка, приведет к waitнемедленному возврату встроенной функции со статусом выхода больше 128, сразу после чего выполняется ловушка.

Это значит, что вам следует запустить его aplayв фоновом режиме wait(как указано выше).


Я могу только предположить, что вы запускаете несколько слушателей, чтобы иметь возможность обслуживать несколько клиентов (все еще максимум одного клиента на порт в любой момент времени). Затем вам иногда нужно убивать aplay, например, когда клиент тихо исчезает и ncне получает уведомления.

Может быть, этовесьподход можно заменить одним socat:

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

Благодаря forkэтому он может обслуживать несколько клиентов на одном порту. Используйте -Tопцию (см. man 1 socat) для завершения устаревших соединений. Даже без -Tних следуеттайм-аут в конце концовВ любом случае. Однако решение уязвимо для DOS-атаки.

Связанный контент