Question

The question applies to a script such as the following:

Script

#!/bin/sh

SRC="/tmp/my-server-logs"

echo "STARTING GREP JOBS..."
for f in `find ${SRC} -name '*log*2011*' | sort --reverse`
do
    (
        OUT=`nice grep -ci -E "${1}" "${f}"`
        if [ "${OUT}" != "0" ]
        then
            printf '%7s : %s\n' "${OUT}" "${f}"
        else
            printf '%7s   %s\n' "(none)" "${f}"
        fi
    ) &
done

echo "WAITING..."
wait

echo "FINISHED!"

Current behavior

Pressing Ctrl+C in console terminates the script but not the already running grep processes.

Was it helpful?

Solution

Write a trap for Ctrl+c and in the trap kill all of the subprocesses. Put this before your wait command.

function handle_sigint()
{
    for proc in `jobs -p`
    do
        kill $proc
    done
}

trap handle_sigint SIGINT

OTHER TIPS

A simple alternative is using a cat pipe. The following worked for me:

echo "-" > test.text; 
for x in 1 2 3; do 
    ( sleep $x; echo $x | tee --append test.text; ) & 
done | cat

If I press Ctrl-C before the last number is printed to stdout. It also works if the text-generating command is something that takes a long time such as "find /", i.e. it is not only the connection to stdout through cat that is killed but actually the child process.

For large scripts that make extensive use of subprocesses the easiest way to ensure the indented Ctrl-C behaviour is wrapping the whole script into such a subshell, e.g.

#!/usr/bin/bash
(
    ...
) | cat

I am not sure though if this has the exactly same effect as Andrew's answer (i.e. I'm not sure what signal is sent to the subprocesses). Also I only tested this with cygwin, not with a native Linux shell.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top