从父节点进程(PM2,NodeJS)运行更新脚本

我有一个名为update.sh的脚本更新服务器。

问题在于; 当我停止PM2进程时,它结束了bash进程(?)。

我无法弄清楚如何从没有链接到父级的父级产生一个进程。 :-S

update.sh

#!/bin/bash # Check we are not already updating. if [ -f update.lock ]; then echo "Already updating. Locked." exit fi # Make the log file. rm update.log touch update.log # Create update lock. touch update.lock echo "Cleaning up" | tee update.log rm -rf the-last-word rm -rf Server echo "Retreving files from BitBucket" | tee update.log git clone git@bitbucket.org:dotdot/dot-project.git # Remove all directories except Server (So we don't have game source code on the Server) echo "Removing game source code" | tee update.log cd the-last-word # Move the Server directory one up. mv Server ../ cd ../ rm -rf the-last-word # Stop the previous server. # == PM2 stop some server name. echo "Stopping server & removing" | tee update.log pm2 delete "Some App" | tee update.log # Update the current & run. echo "Installing node modules" | tee update.log cd Server npm install | tee update.log # Start the server again # == PM2 start some server name. echo "Starting node server" | tee update.log NODE_ENV=production pm2 start bin/www.js --name "Some App" | tee update.log # Remove lock file. cd .. rm update.lock 

现在我使用节点(express route)运行这个脚本。

admin.js

 // Update server app.use("/admin/update", authMiddleware, function(req, res, next) { console.log('Updating server from script.'); const { spawn } = require('child_process'); const deploySh = spawn('sh', [ 'update.sh' ], { cwd: '/www/thelastword/', env: Object.assign({}, process.env, { PATH: process.env.PATH + ':/usr/local/bin' }) }); res.status(200).json('Updating Server'); }); 

更新 – nohup

如果admin.js是服务器进程的一部分,请尝试nohup

 const deploySh = spawn('sh', [ 'nohup ./update.sh' ], { cwd: '/www/thelastword/', env: Object.assign({}, process.env, { PATH: process.env.PATH + ':/usr/local/bin' }) }); 

nohup甚至允许subprocess运行,甚至父母被杀害。

https://unix.stackexchange.com/questions/137759/why-use-nohup-rather-than-exec引用:

nohup运行SIGHUP信号被忽略的特定程序。 当一个terminalclosures时,内核发送SIGHUP给该terminal的控制进程(即shell)。 Shell将SIGHUP发送到在后台运行的所有作业。 使用nohup执行作业可防止terminal死机(例如,如果您已远程login且连接断开或closuresterminal仿真程序),以此方式终止该作业。

参考:

更新 – 简单的testing

我做了一个简单的testing,bash在pm2 delete后没有退出。

伪server.js

 var pid = require('process').pid; var server = require('net').createServer().listen(); 

test.sh

 echo "start dummy." pm2 start ./dummy-server.js --name 'Dummy' echo "stop dummy." pm2 delete 'Dummy' echo "Sleep 5sec" sleep 5 echo "Done." 

输出:

 start dummy. [PM2] Starting ./dummy-server.js in fork_mode (1 instance) [PM2] Done. ┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │ ├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────────────┼──────────┤ │ Dummy │ 0 │ fork │ 9328 │ online │ 0 │ 0s │ 15.219 MB │ disabled │ └──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────────────┴──────────┘ Use `pm2 show <id|name>` to get more details about an app stop dummy. [PM2] Applying action deleteProcessId on app [Dummy](ids: 0) [PM2] [Dummy](0) ✓ ┌──────────┬────┬──────┬─────┬────────┬─────────┬────────┬────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │ └──────────┴────┴──────┴─────┴────────┴─────────┴────────┴────────┴──────────┘ Use `pm2 show <id|name>` to get more details about an app Sleep 5sec Done. 

update.sh在停止之前删除/更改服务器目录。 有时候会造成意想不到的/奇怪的行为。

我修改update.sh如下:

 #!/bin/bash # Check we are not already updating. if [ -f update.lock ]; then echo "Already updating. Locked." exit fi # Make the log file. rm update.log touch update.log # Create update lock. touch update.lock # --- Stop server before deleting its directory! # Stop the previous server. # == PM2 stop some server name. echo "Stopping server & removing" | tee update.log pm2 delete "Some App" | tee update.log echo "Cleaning up" | tee update.log rm -rf the-last-word rm -rf Server echo "Retreving files from BitBucket" | tee update.log git clone git@bitbucket.org:dotdot/dot-project.git # Remove all directories except Server (So we don't have game source code on the Server) echo "Removing game source code" | tee update.log cd the-last-word # Move the Server directory one up. mv Server ../ cd ../ rm -rf the-last-word # Update the current & run. echo "Installing node modules" | tee update.log cd Server npm install | tee update.log # Start the server again # == PM2 start some server name. echo "Starting node server" | tee update.log NODE_ENV=production pm2 start bin/www.js --name "Some App" | tee update.log # Remove lock file. cd .. rm update.lock