从命令行停止node.js程序

361

我有一个简单的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)

我关闭程序的方式不对吗?我该如何防止这种情况发生?


5
值得一提的是,在*nix系统中,按下Ctrl-Z可以挂起一个命令,而不是关闭它。如果你在按下Ctrl-Z后输入fg,你会回到你离开的地方。所以你之前的节点仍在运行。如果你对其他命令这样做,请小心! - ruffin
4
@ruffin 这应该是一个答案。如果您执行了 Ctrl+Z 操作,则恢复进程的适当方法是使用 fg 命令,然后使用 Ctrl+C 命令彻底终止它。 - Metagrapher
19个回答

422
为了结束程序,您应该使用 Ctrl + C。这样做会发送SIGINT信号,使程序能够优雅地结束,并解除其监听的所有端口。
另请参阅:https://superuser.com/a/262948/48624

29
我无法使用 Ctrl + C 快捷键。只有输入 ^C 才会出现在控制台中,程序也不会退出。 - Eleeist
2
@Eleeist,你用什么终端?它对我来说非常好用。 - Brad
4
@Eleeist,你可能已经重新映射了键盘。 Ctrl + C 可以正常工作。无论如何,这与你真正的问题是两个不同的问题。你应该在SuperUser.com上发布一个“Ctrl + C无法工作”的问题。 - Brad
1
@jt0dd,你总是可以使用 kill -9 命令,但我不会这么做。你确定你的应用程序还在占用这些端口吗?我从来没有遇到过这个问题。当我的应用程序结束时,连接总是立即终止的。我建议你可以使用 netstat 命令来确定是否是你的应用程序或其他程序仍然在使用该端口。 - Brad
1
当我在使用其他语言的键盘类型时,我遇到了这个问题。请确保您的Mac输入语言为英语。 - Fa.Shapouri
显示剩余11条评论

404

Ctrl+Z会暂停程序,这意味着程序仍然在运行。

Ctrl+C 会真正杀死程序。

你也可以手动杀死程序,方法如下:

ps aux | grep node

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

kill -9 PROCESS_ID

这也可能起作用

killall node

11
小心使用“killall node”命令,如果有其它进程名称中包含了“node”这个关键词,你可能会误杀一些你不想杀掉的进程。请谨慎操作。 - Samuel Bolduc
5
如果你可以接受结束所有进程的话,那么将 killall node 放在你的回答中可能是最简单、最可靠的选择。建议你修改一下回答。 - Boern
6
"killall"未被识别为内部或外部命令、可执行的程序或批处理文件。我是否漏掉了什么? - Ayyash
我退出了 SSH 会话,但保持节点服务器运行状态。当再次登录时,我不得不使用 kill -9 PROCESS_ID 选项。 - Ifta
使用-9的目的是什么? - Eve
显示剩余3条评论

41

或者你可以在一行代码中完成所有操作:

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

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


3
你可以尝试以下命令:ps -ef | grep "node" | awk '{print $2}' | xargs kill -9该命令的作用是:查找所有名称中含有"node"的进程,并强制结束它们。 - frymaster
似乎可以工作,但不能正确地返回提示符。你有什么想法? - user736893

35

恢复和终止进程:

Ctrl+Z 暂停它,这意味着它仍在作为一个挂起的后台进程运行。

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

  1. 使用命令 fg 恢复进程到前台。

  2. 输入 Ctrl+C 正确地终止它。


或者您可以手动终止它,如下所示:

注意:以下命令可能需要 root 权限,因此使用 sudo ...

pkill -9 node

或者,如果您没有pkill,可以尝试以下方法:
killall node

也许是这样的情况:
kill $(ps -e | grep node | awk '{print $1}')

有时进程列表中会列出它自己的grep进程,这种情况下你需要:
kill $(ps -e | grep dmn | awk '{print $2}')

感谢评论区的@ruffin提供帮助。我遇到同样的问题,他的评论帮助我自行解决了这个问题。


23

如果您正在交互式运行Node.js(REPL):

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

process.exit()

或者只需使用Ctrl + D


22

要退出 Node.js REPL,您可以输入 .exit


3
假设你一开始就在REPL中。那如果我有一个正在运行的Node脚本呢? - IgorGanapolsky

20

在Linux中尝试:pkill node

在Windows中:

Taskkill /IM node.exe /F
或者
from subprocess import call

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

在我的Windows10上,使用Taskkill /IM node.exe /F命令成功关闭了运行在USB上的Node.js。我使用pm2来启动/停止Node.js,但是这并不能完全停止Node.js,这意味着在执行pm2 stop后,Node.js仍在运行,无法安全地弹出USB。你提供的解决方案非常完美! - user2677034

17

$ sudo killall node 在另一个终端上适用于 mac,而 killall node 不起作用:

$ killall node
No matching processes belonging to you were found

14

你可以使用以下命令在本地服务器上关闭指定端口(此处为8000):

http://localhost:8000/ kill PID(进程ID):

$:lsof -i tcp:8000

它将给您以下TCP组:

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

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

$:kill -9 21521

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


切入正题!谢谢。 - Fawkes

9

你可以使用fuser来达到你想要的目的。

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

fuser <<target_port>>/tcp

假设端口是8888,那么命令就是:
fuser 8888/tcp

要终止运行在某个端口上的进程,只需添加 -k 开关。

fuser <<target_port>>/tcp -k

示例(端口为8888):

fuser 8888/tcp -k

就这样!它将关闭监听端口的进程。

在运行服务器应用程序之前,我通常会这样做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接