Reputation: 2358
I want to put couple of function into my .bashrc
.
The functions may execute for a long time so I'd like to be able to kill them with CTRL+C
and print some information when this happens. I can capture CTRL+C
by trapping SIGINT
but I'm not sure what is the correct way to set different trap handlers for different functions inside the same script (.bashrc
).
I came up with this solution which seems to work:
function foo()
{
trap 'echo "foo() stopped"' SIGINT
while true; do
sleep 1
echo "foo() working..."
done
}
function bar()
{
trap 'echo "bar() stopped"' SIGINT
while true; do
sleep 1
echo "bar() working..."
done
}
Example output:
$ foo
foo() working...
foo() working...
^Cfoo() stopped
$ bar
bar() working...
bar() working...
^Cbar() stopped
Now, my questions are:
trap ...
inside a function it resets signal handler for the whole bash session (process)? Or is it creating a new handler each time?Upvotes: 1
Views: 1588
Reputation: 212634
Yes, the trap is resetting things globally. It would probably be good to reset it to its original value when the function ends. Something like:
foo() {
old=$(trap -p SIGINT)
trap 'echo "foo() stopped"' SIGINT
...
eval set -- "$old"
trap "$3" SIGINT
}
OTOH, it's probably more robust to run the function as a subshell, which would have the effect of only setting the trap for the subshell. Doing this is as simple as using (
and )
in the function definition:
foo()
(
trap 'echo "foo() stopped"' SIGINT
while true; do
sleep 1
echo "foo() working..."
done
)
Upvotes: 4