VictorJimenez99
VictorJimenez99

Reputation: 375

How do you kill a running process in a bashscript without killing the script?

How do you kill a running process in a bash script without killing the script?

Goal

So... I need to kill a running process to continue with the execution of my script.

Here´s a stripped down version of my script:

# Setup
echo "Use ctrl+C to stop gathering data..."
./logger
#------------------
echo "Rest..."

I need to be able to kill ./logger without killing my script

Expected vs Actual Results

I was expecting a result like this:

Use ctrl+C to stop gathering data...
^C
Rest...

but it stops when I kill the program

use ctrl+C to stop gathering data...
^C

The ./logger command is a C program that already handles the SIGINT signal (Ctrl + C) but it won't stop until it receives it. Is there a way to stop the program without killing my script?

The C Program is not important but it looks something like this

#include <stdio.h>
#include <signal.h>

int flag = 1;

void handler(int i)
{
     flag = 0;
}

int main(int argc, char** argv)
{
    signal(SIGINT, handler);
    while(flag)
    {
       usleep(10000);
    }
}

Upvotes: 4

Views: 743

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 753455

If you type control-C at the terminal where the script is running, the signal goes to all the processes — the logger program and the script. And the script terminates because you've not told it to ignore signals while the logger is run. You can do that using the trap command but you'll need to undo the trapping before running the C program. See the Bash manual on Signals too.

For example, I have a program dribbler that generates messages, one every second by default, but it is configurable. I'm using it as a surrogate for your ./logger program. The -m options specifies the message; the -n option requests that the messages are numbered, and the -t option specifies output to standard output (instead of a file which it writes to by default).

#!/bin/bash
#
# SO 6418-0134

program="dribbler -t -n -m Hello"
echo "About to run '$program' command"

trap "" 2
(trap 2; $program)

echo "Continuing after '$program' exits"
sleep 1
echo "But not for long"

The sub-shell is necessary. When I run that script (trapper.sh), I get, for example:

$ bash trapper.sh
About to run 'dribbler -t -n -m Hello' command
0: Hello
1: Hello
2: Hello
3: Hello
^CContinuing after 'dribbler -t -n -m Hello' exits
But not for long
$

Incidentally, POSIX defines a command logger that writes messages using the syslog() function(s) to the syslog daemon.

It might also be worth reviewing the Q&A about Sending SIGINT to forked exec process which runs a script does not kill it, especially the accepted answer and its links to Q&A on other Stack Exchange sites, as it matters that you and I both executed a C program, not a shell script.

Upvotes: 5

Related Questions