【问题标题】:Stop node.js program from command line从命令行停止 node.js 程序
【发布时间】:2012-05-18 08:22:01
【问题描述】:

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

我是否以错误的方式关闭程序?我怎样才能防止这种情况发生?

【问题讨论】:

  • 可能值得在 *NIX 上添加 Ctrl-Z suspends 一个命令,并且不会关闭它。如果您在 Ctrl-Z 之后键入 fg,您将回到上次中断的地方。因此,您之前的节点仍在运行。请注意您是否也在为其他命令执行此操作!
  • @ruffin 这应该是一个答案。如果您已经完成了Ctrl+Z 操作,那么正确的方法可能是fg 来恢复进程,然后Ctrl+C 来正确终止它。

标签: node.js command


【解决方案1】:

要结束程序,您应该使用 Ctrl + C。如果你这样做了,它会发送SIGINT,这允许程序优雅地结束,从它正在侦听的任何端口中解除绑定。

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

【讨论】:

  • Ctrl + C 对我不起作用。只有^C 被输入到控制台,程序不会退出。
  • @Eleeist,你用什么做终端?它对我很有用。
  • @Eleeist,您可能已经重新映射了您的密钥或其他东西。 Ctrl+C 工作正常。无论如何,这是与您的实际问题不同的问题。您应该在 SuperUser.com 上发布“Ctrl+C 不起作用”的问题。
  • @jt0dd 你总是可以kill -9,但我不会。您真的确定您的应用程序仍然是保持端口打开的应用程序吗?我从来没有遇到过这个问题。一旦我的应用程序结束,连接总是会立即终止。我会使用 netstat 来确定您的应用程序或其他东西是否在该端口上徘徊。
  • 我在其他语言上使用键盘类型时遇到了这个问题。确保您的 mac 输入语言是英语
【解决方案2】:

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

Ctrl+C 实际上会杀死它。

你也可以像这样手动杀死它:

ps aux | grep node

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

kill -9 PROCESS_ID

这也可能有效

killall node

【讨论】:

  • ctrl+c 会起作用,但这些命令都不适合我。我不知道为什么?我正在寻找命令行解决方案
  • 小心killall节点,如果它们匹配“node”,你可能会杀死你不想杀死的进程
  • 你可能想在你的答案中向上移动killall node,因为这确实是最简单和最可靠的选择(只要你可以杀死所有实例)
  • 'killall' 不是内部或外部命令、可运行程序或批处理文件。我错过了什么吗?
  • 这里也一样...没有答案?它说'killall'未被识别。其他命令也不起作用。我需要重新启动计算机吗?
【解决方案3】:

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

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

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

【讨论】:

  • 或者,您可以随时尝试:ps -ef | grep "节点" | awk '{打印 $2}' | xargs 杀死 -9
  • 似乎有效,但无法正确返回提示。想法?
【解决方案4】:

恢复并终止进程:

Ctrl+Z suspends it, which means it is still running as a suspended background process.

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

  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}')

.


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

【讨论】:

    【解决方案5】:

    你可以输入.exit 退出node js REPL

    【讨论】:

    • 假设你一开始就在 REPL 中。如果我有一个节点脚本正在运行怎么办?
    【解决方案6】:

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

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

    process.exit()
    

    或者直接使用 Ctrl + D

    【讨论】:

      【解决方案7】:

      $ sudo killall node 在另一个终端上可以在 ma​​c 上工作,而killall node 不工作:

      $ killall node
      No matching processes belonging to you were found
      

      【讨论】:

        【解决方案8】:

        在 linux 上试试:pkill node

        在窗户上:

        Taskkill /IM node.exe /F
        

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

        【讨论】:

        • Taskkill /IM node.exe /F 在 windows10 上为我工作,node.js 在 USB 上运行。我正在使用 pm2 启动/停止,但这不会停止 node.js,这意味着您无法安全地弹出 USB,因为 node.js 在 pm2 停止后仍然运行。您的解决方案非常完美!
        【解决方案9】:

        您可以使用 fuser 来完成您想要完成的工作。

        为了获取端口上运行的任务的进程ID,您可以这样做:

        fuser <<target_port>>/tcp
        

        假设端口是8888,命令变成:

        fuser 8888/tcp
        

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

        fuser <<target_port>>/tcp -k
        

        示例(端口为 8888):

        fuser 8888/tcp -k
        

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

        【讨论】:

          【解决方案10】:

          你可以在 localserver kill(这里: 8000) 中执行以下命令

          http://localhost:8000/kill PID(processId):

          $:lsof -i tcp:8000
          

          它将为您提供以下 TCP 组:

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

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

          $:kill -9 21521
          

          会杀掉TCP*:8000对应的processId

          【讨论】:

            【解决方案11】:

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

            当 REPL 通过接收.exit 命令作为输入退出,用户按下&lt;ctrl&gt;-C 两次以发出 SIGINT 信号,或按下&lt;ctrl&gt;-D 以在输入流。侦听器回调在没有任何参数的情况下被调用。

            总结一下,你可以通过以下方式退出:

            1. 在 nodejs REPL 中输入 .exit
            2. 按两次&lt;ctrl&gt;-C
            3. &lt;ctrl&gt;-D
            4. process.exit(0) 表示从 REPL 中自然退出。如果您想返回任何其他状态,您可以返回一个非零数字。
            5. process.kill(process.pid) 是在您的代码或 REPL 中使用 nodejs api 杀死的方法。

            【讨论】:

              【解决方案12】:

              对于 MacOS

              1. 打开终端
              2. 运行以下代码并回车

                 sudo kill $(sudo lsof -t -i:4200)
                

              【讨论】:

                【解决方案13】:

                如果你想用npm stop 或类似的东西来停止你的服务器。您可以编写杀死服务器进程的代码:

                require('child_process').exec(`kill -9 ${pid}`)
                

                查看此链接了解详情: https://gist.github.com/dominhhai/aa7f3314ad27e2c50fd5

                【讨论】:

                  【解决方案14】:

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

                  管理节点服务器进程的一种简洁方法是使用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

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

                  【讨论】:

                    【解决方案15】:

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

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

                    为此,我确保我的node 呼叫尽可能具体。例如,我没有从应用程序目录调用node server.js,而是调用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,正如其他人提到的那样。

                    【讨论】:

                      【解决方案16】:

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

                      【讨论】:

                        【解决方案17】:

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

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

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

                        停止2,停止3...

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

                        有关通过端口查找进程的更多信息:Who is listening on a given TCP port on Mac OS X?

                        【讨论】:

                          【解决方案18】:

                          对于 Windows,首先使用您的端口号搜索 PID

                          netstat -ano | findStr "portNumber"
                          

                          之后,终止任务,确保您位于“c”驱动器的根目录 命令将是taskkill /F /PID your pid

                          【讨论】:

                            【解决方案19】:

                            如果您使用的是 VS Code 和终端,请先从右侧下拉菜单中选择节点,然后按 Ctrl + C。然后它会起作用

                            出现提示时按 y。

                            谢谢

                            【讨论】:

                              猜你喜欢
                              • 2012-06-20
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2013-03-09
                              • 2013-12-07
                              相关资源
                              最近更新 更多