3

我刚刚写了一个shell脚本来控制一个模块的启动和停止。一切似乎都很正常,直到我发现停止命令导致意外。

我使用命令kill -s SIGKILL -- -gpid杀死一组进程。我使用/bin/sh来运行这样的命令

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

它回答了错误

/bin/sh:第 0 行:kill:SIGKILL:无效的信号规范

然后我用 替换了/bin/sh/bin/bash所以命令是

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

它没有回答任何错误。所以我总结出 bash 和 sh 之间的差异导致结果的解释。但是,当我ls使用时/bin/sh,我发现/bin/sh是指向 的符号链接/bin/bash,因此命令应该是相同的。

我发现命令语法kill -s SIGKILL不是推荐的语法,kill -s KILL推荐。

所以我用 KILL 替换了 SIGKILL,命令是

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

它没有回答任何错误。如上所述,任何人都可以解释这种情况。

4

3 回答 3

4

编写此命令的唯一真正可移植的方法是

kill -9 -$gpid

指定信号名称而不是信号编号的方法都不适用于 90 年代中期冻结其 shell 实用程序的 Unix,除了 Linux 和开源 BSD 之外,基本上都是所有这些。但是,SIGKILL 是可靠的 9 号信号,并且一直如此(从 V7 开始,如果不是更早的话)。

特殊参数--也不是可移植的,在这种情况下是不必要的。

如果你想对它更有礼貌(发送 SIGTERM 代替)然后使用

kill -15 -$gpid

同样,这个数字一直可靠到 V7。

于 2013-05-07T18:45:53.307 回答
3

当 bash 被调用时sh(例如,通过符号链接,如您的情况),它使用一种sh兼容模式,其中大多数现代功能都被关闭。我敢打赌,它sh正在调用外部二进制文件kill,但它无法识别SIGKILL,但是 bash 调用正在使用它的内置函数,而该内置函数可以。

于 2013-05-07T17:39:35.283 回答
2

这都是关于bash 兼容性的。使用快速修复,/bin/bash因为sh无法识别 SIGINT 或其他功能。

于 2013-12-23T10:06:53.297 回答