Como parar um loop infinito em execução em segundo plano?

4

Existe uma opção para deixar um loop while infinito, quando ele está sendo executado em segundo plano como uma função, parar e começar a correr a qualquer momento com uma variável local? Eu já tentei muitas opções, só que não consegui encontrar uma solução legal. A única maneira que eu poderia fazê-lo funcionar é ler um arquivo de texto externo de dentro do loop while. E em pontos especificados no programa, escrevendo um 0 ou 1 para aquele arquivo de texto.

O que estou fazendo agora é:

    #!/bin/bash

intr(){ while true                  # function endless while loop start 
        do 
        sleep 0.5                   # execute function every x time
        var1='grep "1" 0or1.txt'    # read file 0or1.txt 
        if [ -n "$var1" ] ; then    # if text =1 execute function, 
        # do some magic..
        fi
        done
        }                           # end function
        intr &                      # execute function as bg process

#some code                          # located some where in the script
echo "1" > 0or1.txt                 # write 1 to start function 
#some code                          # this should be a local variable??


#some code                          # located some where in the script               
echo "0" > 0or1.txt                 # write 0 to stop function
#some code                          # this should be a local variable??
    
por Underscore 27.02.2016 / 00:19

2 respostas

1

A partir da discussão nos comentários abaixo da pergunta ficou claro que o que o OP quer é essencialmente pausar a função de background. Citação:

  

@ serg, o objetivo principal é deixar esse código funcionar como um   interromper. Em vários pontos do programa eu preciso desativar o   "interromper" e em vários pontos eu preciso ativá-lo. (não é um   evento de tempo.)

É possível fazer isso com -SIGSTOP e -SIGCONT . Estes dois sinais são essencialmente pausa e botões de reprodução de um processo. Abaixo está o script de demonstração modificado do que eu postei originalmente. Essencialmente, eu criei a função infinita como um processo em segundo plano, e primeiro envie -SIGSTOP e, em seguida, -SIGCONT para ela. O grande ponto importante aqui é que o processo em segundo plano continuará a rodar mesmo que o processo principal saia, então no meu exemplo abaixo a interrupção não iria parar de enviar para o console, a menos que eu emitisse kill 1234 de outro terminal, onde 1234 é a função PID relatada do script. Então cuidado com isso

$ ./someInfiniteLoop.sh                                        
We are in the main, about to spawn the interrupt function
Parent process (the script itself)  7119
Captured 7120
>>>> HEY I'M THE 1 SECOND INTERRUPT
>>>> HEY I'M THE 1 SECOND INTERRUPT
>>>> HEY I'M THE 1 SECOND INTERRUPT
Sending SIGSTOP to  7120
Funciton paused; waiting 3 seconds
You could do something else when function is paused
Function resumed
>>>> HEY I'M THE 1 SECOND INTERRUPT
>>>> HEY I'M THE 1 SECOND INTERRUPT
>>>> HEY I'M THE 1 SECOND INTERRUPT

Código-fonte do script de demonstração:

#!/bin/bash
# use the line bellow if you want to silence error messages
# exec 2>/dev/null
endless()
{
  while true
  do

     echo ">>>> HEY I'M THE 1 SECOND INTERRUPT"
  sleep 1
  done
}

echo 'We are in the main, about to spawn the interrupt function'
echo "Parent process (the script itself)  $$"

endless &
endless_pid="$!"
echo "Captured $endless_pid"
sleep 3

echo 'Sending SIGSTOP to ' $endless_pid
kill -SIGSTOP $endless_pid
[ $? -eq 0  ] && echo 'Funciton paused; waiting 3 seconds' || echo 'Something is wrong'

echo 'You could do something else when function is paused'

sleep 3

kill -SIGCONT $endless_pid

[ $? -eq 0   ] && echo 'Function resumed' || echo 'Something is wrong'

sleep 3 && exit 0 

Você pode querer ler também:

por Sergiy Kolodyazhnyy 27.02.2016 / 06:28
1

Use o break incorporado para parar o loop while .

De help break :

break: break [n]

Exit for, while, or until loops.

Exit a FOR, WHILE or UNTIL loop.  If N is specified, break N enclosing
loops.

Exit Status:
The exit status is 0 unless N is not greater than or equal to 1.

Então, no seu snippet, você pode fazer:

while :; do
    if [ -n "$var1" ] ; then
        break
    fi
done

Ou ainda mais curto:

while :; do
    [ -n "$var1" ] && break
done

Para passar qualquer entrada para a função, use parâmetros posicionais, ou seja, argumentos. O primeiro argumento pode ser recuperado por , segundo e assim por diante.

Por exemplo, se você chamar a função foobar por:

foobar spam

Na função, você pode usar obter spam usando :

$ foobar () { echo "This is " ;}

$ foobar spam
This is spam
    
por heemayl 27.02.2016 / 00:27

Tags