从命令行停止node.js程序


304

我有一个侦听端口的简单TCP服务器。

var net = require("net");

var server = net.createServer(function(socket) {
    socket.end("Hello!\n");
});

server.listen(7777);

我先将其启动node server.js,然后在Mac上使用Ctrl + Z将其关闭。当我尝试再次运行它时,出现node server.js以下错误消息:

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
          ^
Error: listen EADDRINUSE
at errnoException (net.js:670:11)
at Array.0 (net.js:771:26)
at EventEmitter._tickCallback (node.js:192:41)

我是否以错误的方式关闭程序?如何防止这种情况发生?


2
可能值得补充的是,Ctrl-Z会在* NIX上挂起命令,并且不会将其关闭。如果fg在Ctrl-Z之后输入,您将回到上次停下的位置。因此,您先前的节点仍在运行。请注意是否还要执行其他命令!
ruffin

1
@ruffin这应该是一个答案。如果您已完成该Ctrl+Z操作,则正确的方法可能是fg恢复该过程,然后Ctrl+C适当终止该过程。
人物传记作者

Answers:


393

要结束程序,您应该使用Ctrl+ C。如果这样做,它将发送SIGINT,从而允许程序正常结束,并与正在侦听的任何端口解除绑定。

另请参阅:https : //superuser.com/a/262948/48624


21
Ctrl + C对我不起作用。仅^C输入到控制台中,程序不会退出。
Eleeist 2012年

1
@Eleeist,您在使用什么作为终端?这对我很有效。
布拉德

2
@Eleeist,您可能已重新映射了密钥或其他内容。 Ctrl+C工作良好。无论如何,那是与实际问题不同的问题。您应该在SuperUser.com上发布“ Ctrl + C不起作用”的问题。
布拉德

1
@ jt0dd您可以始终这样做kill -9,但我不会。您实际上确定您的应用程序仍然是保持端口打开的状态吗?我从来没有那个问题。一旦我的应用程序结束,连接总是立即终止。我将使用netstat来确定您的应用程序或其他内容是否在该端口上徘徊。
布拉德(Brad)

1
当我在其他语言上使用键盘类型时,我遇到了这个问题。确保您的Mac输入语言为英语
Fa.Shapouri

325

Ctrl+ Z挂起它,这意味着它仍然可以运行。

Ctrl+ C实际上会杀死它。

您也可以像这样手动将其杀死:

ps aux | grep node

找到进程ID(从左数第二个):

kill -9 PROCESS_ID

这可能也可以

killall node

ctrl + c可以工作,但是这些命令都不适合我。我不知道为什么?我正在寻找命令行解决方案
生气的猕猴桃

7
小心killall节点,如果它们匹配“ node”,则可能会杀死不想杀死的进程
Samuel Bolduc

1
您可能想提高killall node答案,因为这确实是最简单,最可靠的选择(只要您可以杀死所有实例即可)
Boern 2016年

4
“ killall”未被识别为内部或外部命令,可操作程序或批处理文件。我想念什么吗?
Ayyash

同样在这里...没有答案?它说“ killall”无法识别。其他命令也不起作用。我需要重启计算机还是什么?
卫理公会

37

或者,您也可以在一行中完成所有这些操作:

kill -9 $(ps aux | grep '\snode\s' | awk '{print $2}')

您可以将“ \ snode \ s”内的节点替换为任何其他进程名称。


2
或者,您可以随时尝试:ps -ef | grep“节点” | awk'{print $ 2}'| xargs kill -9
frymaster

似乎可以正常工作,但无法正确提示我。有什么想法吗?
魔鬼的拥护者

25

恢复并终止该过程:

Ctrl+ Z将其挂起,这意味着它仍作为已挂起的后台进程运行。

您现在可能会在终端提示下...

  1. fg发出命令以在前台恢复该过程。

  2. 输入Ctrl+ C以正确杀死它。


另外,您可以这样手动将其杀死:

注意:以下命令可能需要root用户,sudo ...您的朋友也需要)

pkill -9 node

或者,如果您没有杀伤力,这可能会起作用:

killall node

也许这样:

kill $(ps -e | grep node | awk '{print $1}')

有时,该进程将列出其自己的grep,在这种情况下,您需要:

kill $(ps -e | grep dmn | awk '{print $2}')


h / t @ruffin来自问题本身的评论。我遇到了同样的问题,他的评论帮助我自己解决了这个问题。


22

您可以键入.exit 以退出节点js REPL


2
前提是您开始使用REPL。如果我正在运行Node脚本怎么办?
IgorGanapolsky'3

18

如果您以交互方式(REPL)运行Node.js:

Ctrl+ C将带您回到>提示符,然后键入:

process.exit()

或只使用Ctrl+ D



13

在Linux上尝试: pkill node

在Windows上:

Taskkill /IM node.exe /F

要么

from subprocess import call

call(['taskkill', '/IM', 'node.exe', '/F'])

5

虽然这是一个较晚的答案,但我是从NodeJS docs找到的:

通过接收.exit命令作为输入,用户按<ctrl>-C两次以向SIGINT发信号或通过按<ctrl>-D以向输入流发出“结束”信号来退出REPL时,将发出“退出”事件。侦听器回调不带任何参数而被调用。

因此,总结一下,您可以退出:

  1. .exit在nodejs REPL中输入。
  2. <ctrl>-C两次。
  3. <ctrl>-D
  4. process.exit(0)意味着从REPL自然退出。如果要返回任何其他状态,则可以返回非零数字。
  5. process.kill(process.pid) 是从您的代码或REPL中使用nodejs api杀死的方法。

5

我添加此答案是因为对于具有生产部署的许多项目,我们都有停止这些过程的脚本,因此我们不必这样做。

一种管理Node Server进程的干净方法是使用forever软件包(来自NPM)。

例:

永久安装

npm install forever -g

运行节点服务器

forever start -al ./logs/forever.log -ao ./logs/out.log -ae ./logs/err.log server.js

结果:

info: Forever processing file: server.js

关闭节点服务器

forever stop server.js

结果

info: Forever stopped process: uid command script forever pid id logfile uptime [0] sBSj "/usr/bin/nodejs/node" ~/path/to/your/project/server.js 23084 13176 ~/.forever/forever.log 0:0:0:0.247

这将彻底关闭您的服务器应用程序。



2

我遇到了一个问题,其中有多个正在运行的节点服务器,我只想杀死其中一个并从脚本中重新部署它。

注意:此示例在Mac上的bash shell中。

为此,请确保node尽可能明确地拨打电话。例如node server.js,我不是从apps目录中调用,而是node app_name_1/app/server.js

然后我可以使用以下方法杀死它:

kill -9 $(ps aux | grep 'node\ app_name_1/app/server.js' | awk '{print $2}')

这只会杀死运行app_name_1 / app / server.js的节点进程。

如果您运行了node app_name_2/app/server.js该节点,进程将继续运行。

如果您决定要杀死它们,可以killall node像其他人提到的那样使用。


2

答案较晚,但在Windows上,使用CTRL + ALT + DEL打开任务管理器,然后杀死Node.js进程将解决此错误。


2

您可以按照以下命令工作,以特定于localserver kill(此处:8000)

http:// localhost:8000 /杀死PID(processId):

$:lsof -i tcp:8000

它将为您提供以下TCP组:

命令PID用户FD类型设备尺寸/关闭节点名称

节点21521 ubuntu 12u IPv6 345668 0t0 TCP *:8000(LISTEN)

$:kill -9 21521

它将杀死对应于TCP *:8000的processId



2

您可以使用热熔器来完成您想做的事情。

为了获取在端口上运行的任务的进程ID,您可以执行以下操作:

fuser <<target_port>>/tcp

假设端口为8888,命令变为:

fuser 8888/tcp

杀死端口上正在运行的进程,只需添加-k开关。

fuser <<target_port>>/tcp -k

示例(端口为8888):

fuser 8888/tcp -k

而已!它将关闭在端口上侦听的进程。我通常在运行服务器应用程序之前执行此操作。


1

我的用例:在MacOS上,通过脚本在不同端口上运行/重新运行多个节点服务器

运行"cd $PATH1 && node server1.js & cd $PATH2 && node server2.js & ..."

stop1"kill -9 $(lsof -nP -i4TCP:$PORT1 | grep LISTEN | awk '{print $2}')"

stop2,stop3 ...

重新运行"stop1 & stop2 & ... & stopN ; run

有关通过端口查找进程的更多信息:谁在Mac OS X上侦听给定的TCP端口?


0

对于Windows,请先使用端口号搜索PID

netstat -ano | findStr "portNumber"

之后,终止该任务,确保您位于“ c”驱动器的根目录中,在此处输入图片说明 并且该命令将是taskkill /F /PID your pid


0

如果您使用的是VS Code,则首先从右侧下拉列表中选择节点,然后执行Ctrl +C。然后它将起作用

在此处输入图片说明

当提示您按y。

在此处输入图片说明

谢谢

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.