Сценарий Bash в фоновом режиме с возможностью управления

#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 для достижения этой цели…