How to Pause (Suspend) a process in Linux with kill signals

Linux KILL command gives you killing opportunities to use SIGNALs. In this post we’re going to Pause (or suspend) and Start an ongoing Linux process.

Problem: The requirement here is to pause a process for certain time and run it only during off hours. The process itself doesn’t have this option and also we cannot stop it in-between, as it will start from the scratch again.

Solution: To resolve this we can think of sending out signals to the process to hint it to Pause or Progress.

A signal is an asynchronous notification sent to a process or to a specific thread within the same process in order to notify it of an event that occurred. When a signal is sent, the operating system interrupts the target process’ normal flow of execution to deliver the signal.

For a command run on terminal we may use ctrl+z to suspend the process.  This internally sends the SIGTSTP signal to the foreground process. Which will basically pause the execution of the command and return control to the terminal.

We can later use bg – to send the execution in background or fg – to bring the process in foreground for proceeding the execution.

Though here we don’t have terminal access and we need to work on a different process using script. We will use KILL command with two signals SIGTSTP & SIGCONT to achieve the goal. All we need is the PID of the target process.

  • SIGTSTP, by default, causes the process to suspend execution. Our Pause.
  • SIGCONT will continue executing the process, if stopped. That’s our Start.

The Script to Pause/Start Linux Process:

[root@nitty-witty sigscripts]# cat ./signal.sh
stop() {
kill -TSTP $1
}

start() {
kill -SIGCONT $1
}

usage() {
echo "$1 [stop|start] process_id"
}

if [ "$#" -eq 0 ]; then
        usage;
        exit 1;
fi

echo "Processing $1 to PID $2"
if [ "$1" = "start" ]; then
        start $2;
elif [ "$1" = "stop" ]; then
        stop $2;
else
        usage;
fi;
[root@nitty-witty sigscripts]#

Sample usage:

[root@nitty-witty sigscripts]# ./signal.sh
 [stop|start] process_id

Watch video in action:

We have used another script which runs a for-loop to print date and counter at certain interval. Here’s one for your reference.

#contd.sh
echo $ > /tmp/mypid
for number in {0..10000}
do
     sleep 1
done
exit 0

Ofcourse the script is quiet basic, just to prove the point and share the idea. Hope you liked this small tutorial of how to pause a process using shell script.

2 comments
  1. Hi there,

    Your script could be improved somewhat, because if you only give it ‘start’ or ‘stop’ as parameter without a second parameter, it will happily execute a kill command, which will fail because the PID is missing.

    For that, I suggest changing the line ‘if [ “$#” -eq 0 ]; then’ to ‘if [ “$#” -lt 2 ]; then’.

    Secondly, the line under ‘usage() {‘ isn’t quite correct. I would suggest the following:
    echo “$(basename $0) [stop|start] PID”

    This way, the actual script name is shown, while the ‘basename’ makes sure the path to the script is left out.

    Lastly, the semicolon after the last line isn’t necessary and looks a bit wacky because there is another line with ‘fi’ that isn’t followed by a semicolon, so the last line looks out of place.

    1. Thank you for your inputs, Richard,
      I was working on a PoC for something and this was one of the section of that which I found useful to share. That said, your recommendations are good. I will look to adjust this.
      Cheers.

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like