reox
reox

Reputation: 5217

Let bash script run all the time but be abortable

I have a bash script like this:

#!/bin/bash
startsomeservice &
echo $! > service.pid

while true; do
    # dosomething in repeat all the time here
    foo bar
    sleep 5
done

# cleanup stuff on abort here
rm tmpfiles
kill $(cat service.pid)

the problem of this script is, that i cant abort it. If i press ctrl+c i just go into the next loop... Is it possible to run a script like this but to have it abortable?

Upvotes: 5

Views: 5986

Answers (4)

tsds
tsds

Reputation: 9020

You can also accomplish the task by something simple like this:

#!/bin/bash

startsomeservice &

read # wait for user input

finish

Upvotes: 0

Mohammed Noureldin
Mohammed Noureldin

Reputation: 16836

I would use:

tail -f /var/log/apache2/error.log & wait ${!}

at the end of the script, I think sleep cause to delay signals handling, but this line will response immediately.

Upvotes: 0

bobah
bobah

Reputation: 18864

The following bash script will keep running until it receives a kill signal. The trap command is responsible for handling the SIGINT.

#!/bin/bash

keepgoing=1
trap '{ echo "sigint"; keepgoing=0; }' SIGINT

while (( keepgoing )); do
    echo "sleeping"
    sleep 5
done

Upvotes: 2

C2H5OH
C2H5OH

Reputation: 5602

Since you are executing the script with Bash, you can do the following:

#!/bin/bash

startsomeservice &
echo $! > service.pid

finish()
{
    rm tmpfiles
    kill $(cat service.pid)
    exit
}
trap finish SIGINT

while :; do
    foo bar
    sleep 5
done

Please note that this behaviour is Bash specific, if you run it with Dash, for instance, you will see two differences:

  1. You cannot capture SIGINT
  2. The interrupt signal will break the shell loop.

Note also that you will break a shell loop with a single C-c when you execute the loop directly from an interactive prompt, even if you're running Bash. See this detailed discussion about SIGINT handling from shells.

Upvotes: 6

Related Questions