杀死一个bash脚本不会终止subprocess

我写了一个testing脚本运行另一个脚本来启动服务器来testing。 当testing完成后, SIGKILL消息被发送到服务器进程,但是当再次运行testing脚本时,服务器会抛出一个EADDRINUSE错误(我在一个node.js环境中),这意味着服务器试图挂载的端口目前正在使用中。 我们试图用SIGKILL杀死的进程仍在运行。 我不认为这是一个特定于节点的问题,而是我的末端教育缺乏教育如何工作。

这里有一些细节,这是我的脚本启动scripts/start-node.sh

 #!/bin/bash node_modules/.bin/babel-node --stage 0 index.js 

这是我的节点服务器称为index.js (我还没有创作任何process事件侦听器):

 Http.createServer(…).listen(PORT, () => console.log(`Server listening on ${PORT}`)) 

启动脚本由节点child_process模块控制:

 var child = child_process.spawn('scripts/start-node.sh') // Later… child.kill('SIGKILL') 

为了杀死一个subprocess和所有它的subprocess,你可以使用process.kill和一个负pid (杀死一个进程组)

 var child = child_process.spawn('scripts/start-node.sh', {detached: true}) // Later… process.kill(-child.pid, 'SIGKILL'); 

有关options.detached详细信息,请参阅child_process文档

在非Windows上,如果设置了分离选项,则subprocess将成为新进程组和会话的组长。

在这里引用一部分man 2 kill一些细节:

如果pid小于-1,则将sig发送给ID为-pid的进程组中的每个进程。


另外一个select是在shell脚本中使用trap来拦截一个信号并杀死所有的孩子,并使用来自node child.kill('SIGTERM') (因为SIGKILL不会被trap截获)

 #!/bin/bash trap 'kill $(jobs -p)' EXIT node_modules/.bin/babel-node --stage 0 index.js 

在你的服务器上有一个处理信号的处理程序

server.js

  var http = require('http'); function handleRequest(request, response){ response.end("Hello"); } var server = http.createServer(handleRequest); server.listen(3000, function(){console.log("listening...")}); process.title="testserver" process.on('SIGQUIT', function() { server.close() }); 

startup.sh

  #!/bin/bash node server.js & echo "started" 

然后有一个“shutdown.sh”。

shutdown.sh

 #!/bin/bash pkill -QUIT testserver & echo "stoped" 

它会杀死所有具有该名称的进程,以防止在“start-node.sh”中产生多个进程。 这样,closures时可以有一些清理代码,例如closures所有连接等。

并在你的testing赛跑者,你可以做

 var exec = require('child_process').exec; exec("./start.sh") // later... exec("./stop.sh") 

你的脚本中是否有退出0

例:

  #!/bin/bash ifconfig exit 0