#bash #function #sockets #background #subshell
#bash #функция #сокеты #фон #подоболочка
Вопрос:
Я хочу создать скрипт, который запускает функцию в фоновом режиме, но оставляет возможность запрашивать у этой функции результаты, приостанавливать, возобновлять или другим способом взаимодействовать с ней.
Для простоты, допустим, я хочу запустить счетчик в фоновом режиме, который увеличивается с каждой секундой. Для взаимодействия с пользователем я оставлю бесконечный цикл с функцией чтения.
Когда я вхожу p
, я ожидаю увидеть текущее $counter
значение.
Когда я вхожу q
, я ожидаю while
, что цикл в loop_counter
функции остановится, как я установил $RUN
false
.
#!/bin/bash
RUN=true
counter=0
print_counter() {
echo "Current value is: $counter"
}
loop_counter() {
while $RUN
do
echo $counter >> file
((counter ))
sleep 1
done
}
loop_counter amp;
while true
do
echo "Print or Quit?"
read x
case $x in
p) print_counter ;;
q) RUN=false; break ;;
*) echo "Use p or q!" ;;
esac
done
wait
Я печатаю $counter
значение file
, просто чтобы посмотреть на другом терминале с tail -f file
Когда я нажимаю p
, я получаю 0
$counter
циклы as в подоболочке.
Когда я нажимаю q
на тормоза скрипта из while
цикла, и он wait
для подпроцесса в фоновом режиме останавливается. К сожалению, это продолжается, поскольку переменная $RUN
в функции loop_counter
остается true
.
Есть идеи, как я могу прочитать текущее значение $counter
или изменить значение $RUN
? Возможно ли создать что-то вроде сокета?
Спасибо
Комментарии:
1.
loop_counter amp;
запускает отдельный асинхронный процесс, который больше не связан с вашим текущим скриптом, поэтому что-то вроде вызоваprint_counter
будет печатать счетчик для текущего процесса, который есть… 0; чтобы включить связь между 2 процессами, вы могли бы рассмотреть а) какое-то решение для сокетов, б) использование комбинацииkill
сигналов и (loop_counter
потребуетсяtrap
указать сигналы и предпринять соответствующие действия), в) передача директив (и данных?) через FIFO / канал и / или файл …2. … вариацией идеи «канала» могут быть сопроцессы, при которых stdin и / или stdout процессов перенаправляются в каналы, а затем сообщения могут передаваться по указанным каналам
3. Я не думаю, что есть отличный прямой способ сделать это, но вы можете делать удивительные вещи с Redis (
redis-cli
), если хотите придерживаться bash.4. Вы можете экспортировать
RUN
counter
переменные и, чтобы они были доступны родительскому скрипту,5. @markp-fuso. Да, ловушка работает хорошо, если постоянно требуется одно действие. Но если требуется несколько разных действий — это не сработает. Я думал использовать socat UNIX-LISTEN:mysocket, fork EXEC:print_counter и запустить его с помощью socat UNIX:mysocket — <<<«p», но socat не может выполнять функции. Просто скрипт. И все же нам нужно запустить socat в фоновом режиме и позволить сценарию работать дальше, что означает, что он запустит новую изолированную подоболочку. Пытаюсь понять, как использовать синергию socat, trap и / или netcat для достижения этой цели…