Trap 'Ctrl + c' for bash script but not for process open in this script
Trap 'Ctrl + c' for bash script but not for process open in this script
I tried to have an interactive program in a bash script :
my_program
And I wish to be able to close it with 'Ctrl + c'.
But when I do it my script is closing as well.
I know about.
trap '' 2
my_program
trap 2
But in this case, I just can't close my_program
with Ctrl + c.
my_program
Do you have any idea how to allow Ctrl + c on a program, but not closing the script running it ?
EDIT : add example
#!/bin/bash
my_program
my_program2
If i use Ctrl + c to close my_program
, my_program2
is never executed because the whole script is exited.
my_program
my_program2
3 Answers
3
You should use trap true 2
or trap : 2
instead of trap '' 2
. That's what "help trap" in a bash shell says about it:
trap true 2
trap : 2
trap '' 2
If ARG is the null string each SIGNAL_SPEC is ignored by the
shell and by the commands it invokes.
Example:
$ cat /tmp/test
#! /bin/sh
trap : INT
cat
echo first cat killed
cat
echo second cat killed
echo done
$ /tmp/test
<press control-C>
^Cfirst cat killed
<press control-C>
^Csecond cat killed
done
tail
You can reset a trap to its default by giving the trap command -
as its action argument. If you do this in a subshell, it won't affect the trap in the parent shell. In your script, you can do this for each command that you need to be interruptible with Ctrl-C:
-
#!/bin/bash
# make the shell (and its children) ignore SIGINT
trap '' INT
.
.
.
# but this child won't ignore SIGINT
(trap - INT; my_program)
# the rest of the script is still ignoring SIGINT
.
.
.
While the accepted answer is probably better and more canonical for shell, this is a great answer in itself in that it introduces the general principle (not shell-specific) for how to do this sort of signal masking/ignoring safely.
– R..
Sep 10 '18 at 17:11
I guess you can
exec my_program
in the subshell, to be slightly more efficient.– Toby Speight
Sep 10 '18 at 17:15
exec my_program
@R.. that's absolutely not shell specific -- if you set a signal to SIG_IGN (that's what trap with an empty string is doing), that state will be inherited through exec(), except for SIGCHLD. That's POSIX mandated behavior. See also the answer to stackoverflow.com/questions/32708086/…
– mosvy
Sep 10 '18 at 17:26
@mosvy: I don't see what part of my comment you're disagreeing with. My whole point was that "mask/ignore before fork, unmask/unignore in the child before exec" is a general principle that's useful to know outside the context of just shell programming.
– R..
Sep 10 '18 at 17:30
This is a very useful answer. As an experienced Linux user, I can say I've never heard of this before. It has quite a lot of uses... you got my upvote and my bookmark.
– Dev
Sep 11 '18 at 4:37
When you use Crtl+C, you interrupt the program ("kill" it).
What you are probably looking for is to suspend your program ("pause" it). For this, you can use Crtl+Z.
Once your program is paused, you can see it using jobs
. For example:[1]+ Stopped ./foobar
Here I only have one job, job #1, but there can be more than one - each job has its own number.
You can control you suspended process using a number of commands, for example bg
, fg
and kill
.bg %1
will restart job #1 in the backgroundfg %1
will restart job #1 in the foregroundkill %1
will kill job #1
Note that you can use bg
and fg
with no arguments if you only have one active job.
Hope this helps.
jobs
[1]+ Stopped ./foobar
bg
fg
kill
bg %1
fg %1
kill %1
bg
fg
Thank you but no, I wish to do Ctrl + c.
– bob dylan
Sep 10 '18 at 12:41
Thanks for contributing an answer to Unix & Linux Stack Exchange!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
How about killing
tail
s instead of killing cats next time?– kubanczyk
Sep 11 '18 at 7:13