Dude
Dude

Reputation: 135

Unable to trap ctrl-c to exit function exit bash script

Following is a script to demonstrate my problem. It's working except that I'm unable to exit upon pressing ctrl-c - it exits, but the working function keeps running and I have to use ps grep kill -9 to get rid of the process.

I've been experimenting with the script and figured out that I cannot simply kill the working function without getting rid of the "Terminated" message from job control. So that's why I trap SIGPIPE to exit the function, which works. By the way, it only seems to work with SIGPIPE, but not SIGINT or INT and I don't understand why. Anyway, I have not found a way yet how to abort on ctrl-c.

Thanks!

#!/bin/bash

bail_out() { unset work; }
ctrl_c() { bail_out; exit; }

working()
{
  trap bail_out SIGPIPE
  trap ctrl_c INT
  echo -n "`tput sc`"
  # a='| / - \'
  a='.oOo oOo. Oo.o o.oO'
  work=1
  while [ "$work" ]; do
    for i in $a; do
      [ "$work" ] && echo -n "`tput rc`Working... $i"
      sleep .1
    done
 done
}

task()
{
  count=0
  while [ $count -lt "$1" ]; do
    ls -l >/dev/null
    sleep .5
    count=$((count +1))
  done
}


working &
task 10
kill -s SIGPIPE %%
echo "`tput rc`task 10 completed"

working &
f_pid=$!
task 11
kill -s SIGPIPE $f_pid
echo "`tput rc`task 11 completed"

Output:

$ ./working
task 10 completed 
task 11 completed

$ ./working
Working... .oOo^C
Working... oOo.

Upvotes: 1

Views: 3823

Answers (1)

Dude
Dude

Reputation: 135

I finally got it. The issue apparently was that I was trap'ing ctrl-c inside a function that ran in the background. Moving "trap ctrl_c INT" out of the "working" function and into the main script solved the issue.

ctrl_c() { kill %%; exit; }


trap ctrl_c INT
working &
task 10
kill -s SIGPIPE %%
echo "`tput rc`task 10 completed"

Upvotes: 5

Related Questions