如何在按下Ctrl+C时触发npm的poststop脚本?
解决Ctrl+C触发时poststop脚本不执行的问题
首先得明确:npm的poststop钩子只有在你主动执行npm stop命令时才会触发,而按下Ctrl+C是向start/dev进程发送SIGINT中断信号,这时候npm不会自动触发poststop,所以mongod进程会留在后台,导致下次启动时提示目录被占用。
下面给你几个贴合不同使用习惯的可行解决方案:
方案一:用Shell的trap命令捕获中断信号
这是最贴合你现有操作习惯的方案——不用改变按Ctrl+C终止的操作,只需修改start和dev脚本,让Shell在收到中断信号时自动执行mongod关闭命令:
"scripts": { "start": "trap 'mongo admin --eval \"db.shutdownServer()\"' INT; NODE_ENV=prod node server.js", "dev": "trap 'mongo admin --eval \"db.shutdownServer()\"' INT; NODE_ENV=dev nodemon server.js" }
配置后,当你按下Ctrl+C时,Shell会先执行trap里定义的mongod关闭逻辑,再终止node/nodemon进程,确保mongod被正确关闭。
方案二:自定义stop脚本并手动触发
如果你愿意调整终止方式,可以补充定义stop脚本,让poststop能正常发挥作用:
"scripts": { "prestart": "mongod", "start": "NODE_ENV=prod node server.js", "stop": "pkill -SIGINT node", // 根据你的进程名调整,比如nodemon进程就换成pkill nodemon "poststop": "mongo admin --eval 'db.shutdownServer()'", "predev": "mongod", "dev": "NODE_ENV=dev nodemon server.js" }
之后启动服务用npm start/npm run dev,终止时不要按Ctrl+C,而是新开终端执行npm stop,这样poststop就会被触发,自动关闭mongod。
方案三:将mongod作为后台进程并管理PID
如果希望mongod在后台静默运行,同时能精准关闭它,可以用PID文件记录进程ID:
"scripts": { "prestart": "mongod --fork --logpath ./mongod.log --pidfilepath ./mongod.pid", "start": "NODE_ENV=prod node server.js", "poststop": "kill $(cat ./mongod.pid) && rm ./mongod.pid", "predev": "mongod --fork --logpath ./mongod-dev.log --pidfilepath ./mongod-dev.pid", "dev": "NODE_ENV=dev nodemon server.js" }
这种方式下,mongod会以守护进程模式启动,PID被存在指定文件里;执行npm stop时,poststop会读取PID并杀掉mongod进程,同时清理PID文件。
内容的提问来源于stack exchange,提问作者Janosh
相关产品推荐
相关产品推荐

