8

I need to run application in every X seconds, so, as far as cron does not work with seconds this way, I wrote a bash script with infinite loop having X seconds sleep in it.

When I have to stop the running script manually, I would like to do it in a correct way - let the application complete functioning and just do not enter the loop for the next time.

Do you have any idea, how this can be achieved? I thought about passing arguments, but I could not find how to pass argument to running script.

Samurai Girl
  • 978
  • 2
  • 8
  • 13

4 Answers4

26

You could trap a signal, say SIGUSR1:

echo "My pid is: $$"
finish=0
trap 'finish=1' SIGUSR1

while (( finish != 1 ))
do
    stuff
    sleep 42
done

Then, when you want to exit the loop at the next iteration:

kill -SIGUSR1 pid

Where pid is the process-id of the script. If the signal is raised during the sleep, it will wake (sleep sleeps until any signal occurs).

cdarke
  • 42,728
  • 8
  • 80
  • 84
2

You may pass some arguments by a file. On each iteration you may read this file and see if your running condtions got changed.

kokosing
  • 5,251
  • 5
  • 37
  • 50
1

The following structure may be appropriate if you have to do some cleanup anyway. Use kill as shown in cdarke's answer.

#===============================================================
#  FUNCTION DEFINITIONS
#===============================================================
# . . .

#===  FUNCTION  ================================================
#          NAME:  cleanup
#   DESCRIPTION:  
#===============================================================
cleanup ()
{
  # wait for active children, remove empty logfile, ..., exit
  exit 0
} # ----------  end of function cleanup  ----------

#===============================================================
#   TRAPS
#===============================================================
trap  cleanup SIGUSR1

#===============================================================
#   MAIN SCRIPT
#===============================================================
echo -e "Script '$0' / PID ${$}"

while : ; do                                # infinite loop
  # . . .
  sleep 10
done
# . . .

#===============================================================
#   STATISTICS / CLEANUP
#===============================================================
cleanup
Fritz G. Mehner
  • 16,550
  • 2
  • 34
  • 41
1

The trap solution posted earlier is good for large loops, but cumbersome for the common case where you are just looping over a single or a few commands. In this case I recommend the following solution:

while whatever; do
    command || break
done

This will exit the loop if command has a non-zero exit code, which will happen if it is interrupted. So unless command handles SIGINT, pressing ctrl-C will both stop the current command and exit the loop.

Edit: After reading your question more closely, I see that you want the current command to continue executing. In that case this solution does not apply.

amaurea
  • 4,950
  • 26
  • 35