Red Lv
Red Lv

Reputation: 1429

linux shell kill signal SIGKILL && KILL

I just written a shell script to control the start and stop of a module. Everything seems normal until I find the stop command result in something unexpected.

I use the command kill -s SIGKILL -- -gpid to kill a group of processes. I use the /bin/sh to run the command like this

/bin/sh -c "kill -s SIGKILL -- -gpid"

which replied the error

/bin/sh: line 0: kill: SIGKILL: invalid signal specification

Then I replaced the /bin/sh with /bin/bash, so the command is

/bin/bash -c "kill -s SIGKILL -- -gpid"

which replied nothing error. so I conclude the explanation that the difference between bash and sh cause the result. However, when I ls the /bin/sh, I found the /bin/sh is a symbolic link to /bin/bash, so the command should be the same.

I found the command syntax kill -s SIGKILL is not in the syntax recommended, kill -s KILL recommended.

so I replaced the SIGKILL with KILL, the command is

/bin/sh -c "kill -s KILL -- -gpid"

which replied nothing error. as described above, anyone could explained this case.

Upvotes: 3

Views: 14199

Answers (3)

tobe
tobe

Reputation: 1741

It's all about bash compatibility. Quick fix to use /bin/bash because sh can't recognize SIGINT or other features.

Upvotes: 2

zwol
zwol

Reputation: 140445

The only truly portable way to write this command is

kill -9 -$gpid

None of the ways to specify a signal name rather than a signal number work on the Unixes that froze their shell utilities in the mid-90s, which is basically all of them except Linux and the open-source BSDs. However, SIGKILL is reliably signal number 9 and has always been so (since V7 if not earlier).

The special argument -- isn't portable either, and is unnecessary in this case.

If you want to be a little more polite about it (sending SIGTERM instead) then use

kill -15 -$gpid

Again, that number is reliable all the way back to V7.

Upvotes: 4

Kevin
Kevin

Reputation: 56049

When bash is invoked as sh (e.g. via symlink, as in your case), it uses a sh compatibility mode where most modern features are turned off. I'd bet sh is calling the external binary for kill, and it doesn't recognize SIGKILL, but the bash invocation is using its builtin, and that builtin does.

Upvotes: 3

Related Questions