node.jsが「npm start」を表すアプリを停止する方法


100

node.jsアプリをExpress v4.xでビルドし、npm startでアプリを起動します。私の質問は、アプリを停止する方法ですか?npm停止はありますか?

npm stopを実装するときにエラーを含めるための編集

/home/nodetest2# npm stop

> nodetest2@0.0.1 stop /home/nodetest2
> pkill -s SIGINT nodetest2

pkill: invalid argument for option 's' -- SIGINT

npm ERR! nodetest2@0.0.1 stop: `pkill -s SIGINT nodetest2`
npm ERR! Exit status 2

回答:


66

はい、npmは停止スクリプトも提供しています。

npm help npm-scripts

prestop、stop、poststop:npm stopコマンドで実行します。

上記のいずれかをpackage.jsonに設定してから、 npm stop

npm help npm-stop

に設定するとapp.js、これを本当に簡単にすることができます。

process.title = myApp;

そして、scripts.jsonで、

"scripts": {
    "start": "app.js"
    , "stop": "pkill --signal SIGINT myApp"
}

とは言っても、これが私ならpm2、git pushに基づいて自動的に処理したものを使用することになります。


まだエラーが発生しました。明らかに、私は行コマンドに精通しています。
ngungo 14

@ngungoというより--signalman pkillpkillについて読むために使用します。
エヴァンキャロル

3
@EvanCarrollアプリの複数のインスタンスが実行されている場合はどうなりますか?
アミットクマールグプタ2017年

1
Angular 4アプリでこれを実装する方法についてのアイデア。具体的には、プロセスタイトルをどこに設定しますか?
kiranghule27

40

ここでの他のすべてのソリューションはOSに依存しています。OSの独立したソリューションでは、socket.ioを次のように使用します。

package.json 2つのスクリプトがあります。

"scripts": {
  "start": "node server.js",
  "stop": "node server.stop.js"
}

server.js-あなたのいつもの急行物がここにあります

const express = require('express');
const app = express();
const server = http.createServer(app);
server.listen(80, () => {
  console.log('HTTP server listening on port 80');
});

// Now for the socket.io stuff - NOTE THIS IS A RESTFUL HTTP SERVER
// We are only using socket.io here to respond to the npmStop signal
// To support IPC (Inter Process Communication) AKA RPC (Remote P.C.)

const io = require('socket.io')(server);
io.on('connection', (socketServer) => {
  socketServer.on('npmStop', () => {
    process.exit(0);
  });
});

server.stop.js

const io = require('socket.io-client');
const socketClient = io.connect('http://localhost'); // Specify port if your express server is not using default port 80

socketClient.on('connect', () => {
  socketClient.emit('npmStop');
  setTimeout(() => {
    process.exit(0);
  }, 1000);
});

試してみる

npm start (通常どおりサーバーを起動するため)

npm stop (これにより、実行中のサーバーが停止します)

上記のコードはテストされていません(これは私のコードの縮小バージョンであり、私のコードは機能します)。どちらの方法でも、socket.ioを使用してサーバーを停止する場合の一般的な方向性を示します。


2
このアプローチの優れている点は、基本的に、コンテナーを含む任意の環境で実行できることです。コンテナーは通常、プロセスの操作方法に非常に制限があります。私の個人的な観点から-それは最もエレガントなアプローチです。
Der Zinger

16

提案された解決策を試したところ、アプリ名が切り捨てられていることに気付きました。process.titlenodejsのドキュメント(https://nodejs.org/docs/latest/api/process.html#process_process_title)を読み、それは言う

LinuxおよびOS Xでは、argvメモリを上書きするため、バイナリ名のサイズとコマンドライン引数の長さの合計に制限されます。

私のアプリは引数を使用しないので、このコード行を追加できます app.js

process.title = process.argv[2];

次に、これらの数行をpackage.jsonファイルに追加します

  "scripts": {
    "start": "node app.js this-name-can-be-as-long-as-it-needs-to-be",
    "stop": "killall -SIGINT this-name-can-be-as-long-as-it-needs-to-be"
  },

本当に長いプロセス名を使用する。 npm startそしてnpm stop当然の仕事は、npm stop常にすべての実行中のプロセスを終了しますが、それは私のためokです。


12

これは、代わりにcmdを使用する、バージョンの問題です。サーバープロセスを強制終了するには、次のコマンドを実行します。

    taskkill -F -IM node.exe

1
複数のノードアプリを実行している場合に問題が発生するため、メインのnode.exeを強制終了することはお勧めしません
user889030

11

MAC OS X(/ BSD)の場合:lsof(list open files)コマンドを使用してみることができます

$ sudo lsof -nPi -sTCP:LISTEN

ここに画像の説明を入力してください

など

$ kill -9 3320

9

netstat -nptlですべてのプロセスを確認してください

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN      1736/mongod     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1594/sshd       
tcp6       0      0 :::3977                 :::*                    LISTEN      6231/nodejs     
tcp6       0      0 :::22                   :::*                    LISTEN      1594/sshd       
tcp6       0      0 :::3200                 :::*                    LISTEN      5535/nodejs 

そして、それは単にPID参照によってプロセスを強制終了します。

kill -9 6231

1
OPはコンソールではなくNPMスクリプトオプションを探していると思います。
Faraji Anderson、

4

これは、以前の回答からのアイデアを組み合わせた別のソリューションです。プラットフォームの独立性に関する懸念に対処しながら、「キルプロセス」アプローチを採用しています。

サーバープロセスツリーの強制終了は、tree-killパッケージに依存しています。一部のツール(などbabel-node)が子プロセスを生成するため、プロジェクトで必要なプロセスツリー全体を強制終了することがわかりました。単一のプロセスのみをkillする必要がある場合は、tree-killを組み込みprocess.kill()メソッドに置き換えることができます。

解決策は次のとおりです(最初の2つの引数spawn()は、サーバーを実行するための特定のレシピを反映するように変更する必要があります)。

build / start-server.js

import { spawn } from 'child_process'
import fs from 'fs'

const child = spawn('node', [
  'dist/server.js'
], {
  detached: true,
  stdio: 'ignore'
})
child.unref()

if (typeof child.pid !== 'undefined') {
  fs.writeFileSync('.server.pid', child.pid, {
    encoding: 'utf8'
  })
}

build / stop-server.js

import fs from 'fs'
import kill from 'tree-kill'

const serverPid = fs.readFileSync('.server.pid', {
  encoding: 'utf8'
})
fs.unlinkSync('.server.pid')

kill(serverPid)

package.json

"scripts": {
  "start": "babel-node build/start-server.js",
  "stop": "babel-node build/stop-server.js"
}

このソリューションは、サーバーから開始スクリプトを切り離すことに注意してください(つまり、npm startすぐに戻り、サーバーが停止するまでブロックされません)。従来のブロッキング動作を使用する場合は、へのoptions.detached引数とspawn()への呼び出しを削除するだけchild.unref()です。


3

すでに試しctrl + cても問題が解決しない場合は、試してみてください。これでうまくいきました。

  1. 管理者としてコマンドラインを実行します。次に、以下のコマンドを実行して、強制終了するプロセスID(PID)を見つけます。ポート番号を入力してください<yourPortNumber>

    netstat -ano | findstr :<yourPortNumber>

ここに画像の説明を入力してください

  1. 次に、PIDを識別した後でこのコマンドを実行します。

    taskkill /PID <typeYourPIDhere> /F

ここに画像の説明を入力してください

http://www.callstack.in/tech/blog/windows-kill-process-by-port-number-157から@mit $ inghへの称賛


2

非常に単純な場合は、プロセスを強制終了します。

localmacpro$ ps
  PID TTY           TIME CMD
 5014 ttys000    0:00.05 -bash
 6906 ttys000    0:00.29 npm   
 6907 ttys000    0:06.39 node /Users/roger_macpro/my-project/node_modules/.bin/webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
 6706 ttys001    0:00.05 -bash
 7157 ttys002    0:00.29 -bash

localmacpro$ kill -9 6907 6906

1

Windowsマシン(Windows 10を使用)の場合、CLIのCTRL + C(キャンセル/中止)コマンドが機能せず、画面は次のように表示されます。

ここに画像の説明を入力してください

最初にEnterキー(または任意のキーで可能)を押してからCTRL + Cを押すと、現在のプロセスでバッチジョブを終了するかどうか尋ねられます。

ここに画像の説明を入力してください

おそらくCTRL + Cは親プロセスのみを終了し、npm startは他の子プロセスで実行されます。Ctrlキーを押しながらCキーを押す前に追加のキーを押す必要がある理由はまったくわかりませんが、コマンドラインを閉じてやり直すよりもうまくいきます。

確認したい関連問題:https : //github.com/mysticatea/npm-run-all/issues/74




0

jsonファイルにアプリを停止するスクリプトがない場合、私が使用するオプションは、cmdでctrl + Cを押すだけです。


-1

すべての(3)solotionは:

1- ctlr + C

2- jsonファイルで、停止するスクリプトを記述します

"scripts":{"stop": "killall -SIGINT this-name-can-be-as-long-as-it-needs-to-be"}、

*コマンドの書き込みより// npm stop //

3- PCを再起動します


7
PCを再起動しますか?なぜメインのサーキットブレーカを裏返さないのですか?:D
stk '10 / 09/19

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.