node.js - 杀死 bash 脚本不会杀死子进程

标签 node.js bash process child-process sigkill

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

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

#!/bin/bash

node_modules/.bin/babel-node --stage 0 index.js

这是我的 Node 服务器,名为 index.js(我还没有编写任何 process 事件监听器):

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

并且启动脚本由 Node child_process模块控制:

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

最佳答案

要杀死一个子进程及其所有子进程,您可以使用 process.kill带有一个否定的 pid(杀死一个进程组)

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

查看 child_process 文档的详细信息 options.detached

On non-Windows, if the detached option is set, the child process will be made the leader of a new process group and session.

这里引用 man 2 kill 的一部分以获得一些细节:

If pid is less than -1, then sig is sent to every process in the process group whose ID is -pid.


另一种选择可能是在您的 shell 脚本中使用 trap 来拦截信号并杀死所有子进程并使用 中的 child.kill('SIGTERM') node(因为SIGKILL不会被trap拦截)

#!/bin/bash

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

关于node.js - 杀死 bash 脚本不会杀死子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33325301/

相关文章:

node.js - 使用 node.js 在 mongoDB 中插入文档

node.js - socket.io 加入房间的问题

bash - AWS Session Manager 未获取 bashrc

Bash 脚本双引号

bash - 在 Bash 中使用二维数据集?

node.js - 使用 Cheerio 抓取时出现问题

java - ProcessBuilder 找不到指定的文件,而 Process 可以

python - 用于启动和停止进程的最佳 Python Web 框架

c - fork 和共享内存

javascript - 解码 Node.js 中的缓冲区