Why would Ctrl-C behave differently than kill -2
Solution 1
One possibility is that the program catches the Ctrl+C sequence. Check the output of stty -a
; the intr
setting indicates which key combination (if any) sends a SIGINT signal, and the isig
indicates whether the signal keys are enabled (-isig
means they are disabled).
If the program consists of several processes, pressing Ctrl+C sends SIGINT to all the processes in the process group. You can obtain the same effect by sending the signal to the process group instead of sending it to one of the processes. To send a signal to a process group, first determine its leader: that's the first process that starts all the others; if you run the process group in the background, that's the PID shown by jobs -l
. The PID of the process group leader is the PGID (process group id); send the signal to its negative. E.g. if the PGID is 1234, run kill -INT -1234
.
If the program consists of a wrapper script and a main application, there are two cases to consider. If there is no cleanup to do, so that the wrapper script terminates as soon as the main aplication terminates, make the wrapper script call exec
:
#!/bin/sh
export SOMEVAR=somevalue
…
exec /path/to/application "$@"
This way the application replaces the script, inheriting its PID. Some shells optimize a script that ends by executing another program, but not all. This approach doesn't work when the script needs to perform some cleanup such as removing temporary files.
Consider making the script detect a signal and transmitting the signal to the application. Here's a sketch of how this goes:
/path/to/application "$@" &
app_pid=$!
trap -INT 'kill -INT $app_pid'
wait $!
rm /temp/file
Solution 2
Based on the questions @Gilles asked in the comments to my original question I realized that the kill -2
command I was sending was targeting the pid of the wrapper script which launched the application instead of the process which handles the signal itself.
Using the pids from my question, kill -s 13405
was not properly signaling the application, but calling kill -s 13509
works as expected.
Now my question is how can I update my wrapper script to propagate a SIGINT to its child processes, but I'll create a separate question for that.
Related videos on Youtube
Mike Deck
Updated on September 18, 2022Comments
-
Mike Deck over 1 year
I have a program which is supposed to handle SIGINT and gracefully shut down. When I run this program from a terminal without backgrounding it I can shut it down just fine using Ctrl-C. Inspecting the logs shows that everything worked as expected.
When I open a separate terminal and call
kill -2 [pid]
orkill -s INT [pid]
it does nothing. I see nothing in the logs and the program continues to run as usual until I hit Ctrl-C in the terminal I launched it from.Are there any differences between how Ctrl-C sends the signal and how kill does?
Additional Details:
The program in question is a Java application launched by a bash shell script which sets up some environment variables (namely
CLASSPATH
) and then callsjava [main class]
. Hitting Ctrl-Z and then runningps
results in the following:$ ps -f UID PID PPID C STIME TTY TIME CMD mdeck 10251 10250 0 11:48 pts/2 00:00:00 -bash mdeck 13405 10251 0 18:12 pts/2 00:00:00 /bin/bash /usr/local/bin/myapp.sh mdeck 13509 13405 25 18:12 pts/2 00:00:03 java com.company.MyApp mdeck 13526 10251 0 18:13 pts/2 00:00:00 ps -f
The output of stty as requested by Gilles is below:
$ stty -a </dev/pts/2 speed 38400 baud; rows 40; columns 203; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
-
Gilles 'SO- stop being evil' almost 12 yearsDoes the program run in a single process? Does the program capture
Ctrl+C
instead of reacting to a signal? What is the output ofstty -a </dev/pts/42
where/dev/pts/42
is the output oftty
in the terminal where you start the process? -
Mike Deck almost 12 years@Gilles, I've updated the question to include some of the information you're requesting.
-