我刚编写了一个shell脚本来控制模块的启动和停止。一切看起来都很正常,直到我发现停止命令导致意外的结果。
我使用命令kill -s SIGKILL -- -gpid
来杀死一组进程。我使用/bin/sh
来运行像这样的命令
/bin/sh -c "kill -s SIGKILL -- -gpid"
回复了错误
/bin/sh: line 0: kill: SIGKILL: invalid signal specification
然后我用/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"
没有回复任何错误。如上所述,任何人都可以解释这种情况。
答案 0 :(得分:3)
当bash被调用为sh
时(例如通过符号链接,就像您的情况一样),它使用sh
兼容模式,其中大多数现代功能都已关闭。我敢打赌sh
正在为kill
调用外部二进制文件,它不识别SIGKILL
,但是bash调用正在使用它的内置函数,而内置函数则使用它。
答案 1 :(得分:3)
编写此命令的唯一真正可移植方式是
kill -9 -$gpid
无指定信号 name 的方式,而不是在90年代中期冻结其shell实用程序的Unix上的信号编号,这基本上都是其中除了Linux和开源BSD之外。但是,SIGKILL可靠信号为9,并且一直如此(因为V7,如果不是更早的话)。
特殊参数--
也不可移植,在这种情况下是不必要的。
如果你想对它更有礼貌(改为发送SIGTERM),那么使用
kill -15 -$gpid
同样,这个数字在回到V7之前是可靠的。
答案 2 :(得分:2)
关于bash compatibility的全部内容。使用/bin/bash
的快速解决方法,因为sh
无法识别SIGINT或其他功能。