【问题标题】:How to exit in Node.js如何在 Node.js 中退出
【发布时间】:2011-07-13 01:49:43
【问题描述】:

用于退出的命令是什么? (即终止 Node.js 进程)

【问题讨论】:

标签: node.js


【解决方案1】:

来自官方nodejs.org 文档:

process.exit(code)

使用指定的代码结束进程。如果省略,则退出使用“成功”代码 0。

使用“失败”代码退出:

process.exit(1);

【讨论】:

  • @Alison 是的,或者更准确地说是code = 0; process.exit(code);
  • 如果你退出,你是否真的不在乎code的值?
  • @Alison 更好的主意是 process.exit() 没有参数,因为代码默认为 0
  • @Armand 你是对的——代码只是一个变量,在这种情况下用于指示参数是什么。所以 .exit(0) 完成了示例所做的一切。
  • @Armand 代码不适合您,它适合运行您的代码。例如,如果您使用process.exit(0); 创建一个exit_0.js 并使用node exit_0.js && echo 'success' 运行它,它将显示“成功”。如果您使用process.exit(1); 创建exit_1.js 并运行node exit_1.js && echo 'success',它不会说“成功”,因为您的进程以非零值退出(这表示shell 的“失败”或“异常退出”)。此外,如果您运行node exit_1.jsnode exit_0.js,您将在$? 中看到不同的值(您可以通过执行node exit_1.js 然后执行echo $? 来检查)。
【解决方案2】:

调用全局process对象的exit方法:

process.exit()

From the docs:

process.exit([exitcode])

以指定的code 结束进程。如果省略,则退出使用“成功”代码0

使用“失败”代码退出:

process.exit(1);

执行节点的shell应该看到退出代码为1

【讨论】:

  • 只是想添加一些东西。如果你正在处理一个请求,你也应该end()这个请求。否则,它只会挂起。
  • @pixelfreak, exit 一点也不误导。您对 Node 的工作方式感到困惑。将 Node 视为服务器本身。它不只是根据需要启动,就像 PHP 在 Apache 之类的 Web 服务器中一样。 Node 甚至根本不需要与 Web 服务器有任何关系!它只是一些 JavaScript 的宿主,有一些漂亮的内置库来做有用的事情。
  • @Brad PHP 是一种通用语言。无需使用 mod_php 运行它或使用 Apache。如果你真的想要的话,你可以像 node 一样在 PHP 中重新实现 httpd,或者像在 node 中一样使用更理智/标准化的方法,比如 FastCGI。
  • 请注意process.exit()不推荐,如this answer below中所述。
  • 有点离题,但我看到人们使用process.exit(-1)。为什么会这样?
【解决方案3】:

如果您在 Unix 终端或 Windows 命令行中并想退出 Node REPL,则...

  • Ctrl + C 两次,或
  • 输入 .exit 并按 Enter,或
  • 在行首按 Ctrl + D(仅限 Unix)

【讨论】:

  • 请注意,除了 Node 之外,Mac 或 Linux 上的 Ctrl+D 快捷键几乎适用于您将遇到的所有 shell 和 REPL,包括 Unix shell(如 Bash)、数据库 shell(如 MySQL 和 PostgreSQL) ,以及用于 Python、PHP 和 Ruby 等编程语言的 REPL。这是我用过的唯一退出 shell 的方法。
  • 对于node REPL,Ctrl+D 退出是标准行为,因此它也适用于 Windows。
  • 按 Ctrl + C(即使在 Mac 上!)
【解决方案4】:

从命令行,.exit 就是你想要的:

$ node
> .exit
$

它记录在REPL docs 中。 REPL (Read-Eval-Print-Loop) 是 Node 命令行的名称。

在普通程序中,使用process.exit([code])

【讨论】:

    【解决方案5】:

    您可以在代码中使用process.exit([errorcode]),其中[errorcode] 是一个可选整数(0 是默认值,表示成功)。

    如果你使用Read Eval Print Loop (REPL),你可以使用Ctrl + D,或者输入.exit

    或者,在 Windows 或 Linux 上,您可以使用 Ctrl + CCtrl + C

    在 Mac 上,命令是 Ctrl + Z, Ctrl + Z

    【讨论】:

    • 两个控制 c 也可以在 mac 上工作,至少在我的 node --version v0.10.18 上工作
    • Control-C 似乎不会取消已经安排好的操作,而在 Mac 上 ctrl-z 会立即终止进程。
    【解决方案6】:

    我有一个我想要的应用程序:

    1. 向用户发送电子邮件
    2. 退出并显示错误代码

    我必须将process.exit(code) 挂钩到exit 事件处理程序,否则邮件将不会发送,因为调用process.exit(code) 会直接杀死异步事件。

    #!/usr/bin/nodejs
    var mailer = require('nodemailer');
    var transport = mailer.createTransport();
    mail = {
      to: 'Dave Bowman',
      from: 'HAL 9000',
      subject: 'Sorry Dave',
      html: 'Im sorry, Dave. Im afraid I cant do <B>THAT</B>.'
    }
    transport.sendMail(mail);
    //process.exit(1);
    process.on('exit', function() { process.exit(1); });
    

    【讨论】:

    • 我想你想要process.exitCode
    • 为了记录:我花了一天的大部分时间试图让 process.exitCode 在我正在构建的命令行工具中为我工作(在 Node v4.3.0 上测试)。但我无法让它表现得像记录的那样。这很可能是commander 的一个边缘案例- 尽管github.com/tj/commander.js/… 让我想知道。不确定是否有其他人在 Node 4 上看到过这个问题,但记录下来以备将来参考。
    • 这是来自指挥官的可能性,我还查看了它的唯一部门 (github.com/zhiyelee/graceful-readlink/…) 但没有骰子。唯一可能的罪魁祸首似乎是:github.com/tj/commander.js/blob/… 具体来说,问题是,即使您设置了process.exitCode = 1,进程也会以代码 0 退出。
    【解决方案7】:

    注意,使用process.exit([number])not recommended 的做法。

    调用process.exit() 将强制进程尽快退出 即使仍有待处理的异步操作也是可能的 尚未完全完成,包括 I/O 操作 process.stdoutprocess.stderr

    在大多数情况下,实际上不需要调用 process.exit() 明确。 Node.js 进程将自行退出,如果 事件循环中没有其他待处理的工作。这 process.exitCode属性可以设置告诉进程哪个退出 进程正常退出时使用的代码。

    例如,以下示例说明了 误用 process.exit() 可能导致打印到 stdout 的数据的方法 被截断和丢失:

    // This is an example of what *not* to do:
    if (someConditionNotMet()) {
      printUsageToStdout();
      process.exit(1);
    }
    

    这是因为 问题是因为在 Node.js 中写入 process.stdout 是 有时是异步的,并且可能发生在多个滴答声中 Node.js 事件循环。但是,调用 process.exit() 会强制 在对stdout 的额外写入之前退出进程 执行。

    而不是直接调用process.exit(),代码应该设置 process.exitCode 并通过避免让进程自然退出 为事件循环安排任何额外的工作:

    // How to properly set the exit code while letting
    // the process exit gracefully.
    if (someConditionNotMet()) {
      printUsageToStdout();  
      process.exitCode = 1;
    }
    

    【讨论】:

    • 这是迄今为止最好的答案。其他答案可能不允许节点在退出前正确处理未决事件,非常难过:(
    • 同意,这应该有更多的赞成票!我有一个节点脚本,它通过 shelljs.exec 启动多个子进程,如果任何子进程失败,我希望我的整个脚本返回错误退出代码。 process.exitCode = 1 在 exec 回调中效果很好(而在其中简单地调用 process.exit(1) 会在所有子进程完成之前退出主脚本!)
    • 我使用了这个答案,发现我的进程从未真正退出。必须按 ctrl-C。
    • 立即处理和未决事件终止有很多用例。这正是process.exit() 的用途。
    • 这不是最好的答案,因为它没有回答问题。相反,它提供了如何为 nodejs 程序开发代码流的最佳实践。
    【解决方案8】:

    正如@Dominic 指出的那样,throwing an uncaught error 是更好的做法,而不是调用 process.exit([code])
    process.exitCode = 1; throw new Error("my module xx condition failed");

    【讨论】:

    • 在“如何在 Node.js 中退出”这个问题的上下文中,这是一个可怕的建议。如果问题专门询问如何在错误时退出,您的建议会更有意义。我强烈建议您以这样的方式表达您的回复,以表明用户按照您的建议进行操作,只有当他们试图在发生错误的情况下退出应用程序时。
    • @rstackhouse,我希望你已经经历过抛出一个未捕获的错误,它指向 --> nodejs.org/api/process.html#process_process_exit_code
    • 抛出的问题是丑陋的堆栈跟踪。避免此堆栈跟踪的任何提示(如果使用不正确,当 CLI 工具想要退出时不相关)?
    【解决方案9】:

    退出

    let exitCode = 1;
    process.exit(exitCode)
    

    有用的退出代码

    1 - 捕获一般错误 2 - 滥用 shell 内置函数(根据 Bash 文档) 126 - 调用的命令无法执行 127 - “找不到命令” 128 - 退出的参数无效 128+n - 致命错误信号“n” 130 - 脚本被 Control-C 终止 255\* - 退出状态超出范围

    【讨论】:

    【解决方案10】:

    这取决于您愿意退出 node.js 进程的原因,但无论如何process.exit()要考虑的最后一个选项。来自文档的引用:

    请务必注意,调用 process.exit() 将强制 进程尽快退出,即使仍有 尚未完全完成的未决异步操作, 包括对process.stdoutprocess.stderr的I/O操作。

    在大多数情况下,实际上不需要调用 process.exit() 明确。 Node.js 进程将自行退出 如果事件循环中没有其他待处理的工作。这 process.exitCode属性可以设置告诉进程哪个退出 进程正常退出时使用的代码。

    让我们介绍一下您可能愿意退出 node.js 进程的可能原因以及为什么您应该避免process.exit()

    案例 1 - 执行完成(命令行脚本)

    如果脚本已经结束并且节点解释器没有退出,这表明一些异步操作仍在等待中。此时使用process.exit() 强制终止进程是错误的。最好尝试了解what is holding your script from exiting in expected way。当你解决这个问题时,你可以使用process.exitCode 将任何结果返回给调用进程。

    案例 2 - 因外部信号终止 (SIGINT/SIGTERM/other)

    例如,如果您愿意优雅地关闭 express 应用。与命令行脚本不同,express 应用程序会无限运行,等待新的请求。 process.exit() 在这里将是一个糟糕的选择,因为它会中断管道中的所有请求。其中一些可能是非幂等的(更新、删除)。客户端永远不会知道这些请求是否在服务器端完成,这可能是客户端和服务器之间数据不一致的原因。唯一好的解决方案是告诉 http 服务器停止接受新请求并等待待处理的请求完成server.close()

    var express = require('express');
    var app = express();
    var server = app.listen(80);
    
    process.on( 'SIGTERM', function () {
       server.close(function () {
         console.log("Finished all requests");
       });
    });
    

    如果它仍然没有退出 - 请参阅案例 1。

    案例 3 - 内部错误

    throw 出错总是更好,你会得到格式良好的堆栈跟踪和错误消息。上层代码总是可以决定他们是否可以处理错误(catch)或让它崩溃进程。另一方面,process.exit(1) 将静默终止进程,并且没有机会从中恢复。这可能是process.exit() 的唯一“好处”,您可以确定该进程将被终止。

    【讨论】:

    • 惊人的反应。 Process.exit() 对于大多数应用程序来说似乎是一种过度杀伤。我正在寻找与 php 的 die() 函数等价的函数...更像:throw new Error('die msg')
    • 如果有一堆代码应该连续执行直到收到关闭请求,是否有任何好的约定来注册事件,允许订阅被放弃以响应关闭请求,不需要使用事件的代码或请求关闭的代码相互了解具体知识?不幸的是,我能想到的唯一一种实现方式是要求任何注册事件的代码也创建一个包装器,其中包含一个用于取消注册的闭包。
    • 这应该是公认的答案。它解释了process.exit()process.exitCode、信号处理和(我想要的)throw new Error 退出。
    【解决方案11】:

    REPL(命令行)

    • ctrl + c两次

    • 输入.exit并回车

    脚本文件

    process.exit(code)
    

    当没有更多异步操作挂起时,节点通常会以 code 0 退出。

    process.exit(1) 应该用于退出失败代码。这将允许我们推断该节点没有正常关闭并被强制关闭。

    还有其他退出代码,例如

    3 - 内部 JavaScript 解析错误(非常非常罕见)

    5 - v8 javascript 引擎中的致命错误

    9 - 无效参数

    完整列表见node exit codes

    【讨论】:

      【解决方案12】:

      如果你想退出 node js 应用程序然后写

      process.exit(1)
      

      在您的代码中

      【讨论】:

      • 1 用于表示应用程序中存在错误,其他答案已经澄清。
      【解决方案13】:

      通过键入taskkill -F -IM node.exe,我能够让我的所有节点进程直接从 Windows 10 上的 Git Bash shell 中终止——这会立即结束我计算机上的所有节点进程。我发现我也可以使用taskkill //F //IM node.exe。不知道为什么 -// 在这种情况下工作。希望这会有所帮助!

      【讨论】:

      • 那是由于 taskkill 本身。您正在杀死进程本身。此外,一个 / 就足够了。
      【解决方案14】:

      按两次Ctrl + C.exit

      > 
      (To exit, press ^C again or type .exit)
      > 
      

      【讨论】:

        【解决方案15】:

        你可以使用process.exit([code])函数。

        如果您想在没有“失败”的情况下退出,请使用代码0

        process.exit(0);
        

        要以“失败”代码1 退出,您可以运行:

        process.exit(1);
        

        失败的“失败”代码特定于应用程序。所以你可以使用你自己的约定。

        【讨论】:

          【解决方案16】:

          打开运行节点应用程序的命令行终端并按Ctrl + C

          如果你想从代码中退出 node js 应用程序,

          process.exit(); // graceful termination 
          process.exit(1); // non graceful termination 
          

          【讨论】:

          • process.exit从不优雅。省略代码只会使用process.exitCode ?? 0
          【解决方案17】:

          node js中的退出有两种方式:

          • 显式调用 process.exit()
          • 或者,如果 nodejs 事件循环已完成所有任务,并且没有什么可做的。然后,节点应用程序将自动退出。

          它是如何工作的?

          如果你想强制执行循环停止进程,你可以使用全局变量process,它是EventEmitter的一个实例。因此,当您调用 process.exit() 时,您实际上会发出 exit 事件,该事件会立即结束所有任务,即使仍有异步操作尚未完成完成。

          process.exit() 将退出代码(整数)作为参数。代码 0 是默认值,这意味着它以“成功”退出。而代码 1 表示它以“失败”退出。

          【讨论】:

            【解决方案18】:

            由于进程是全局对象,您不需要导入任何模块。以下函数退出或杀死当前节点进程。

            process.exit(代码)

            process.kill(process.pid)

            process.abort()

            【讨论】:

              【解决方案19】:

              如果您在 Windows 中,请转到任务管理器,然后转到进程,查找名为“节点”的进程,然后用鼠标右键单击它,然后单击“结束进程”选项。

              【讨论】:

                【解决方案20】:
                import mongosse from 'mongoose'
                import dotenv from 'dotenv'
                import colors from 'colors'
                import users from './data/users.js'
                import products from './data/products.js'
                import User from './models/userModel.js'
                import Product from './models/productModel.js'
                import Order from './models/orderModel.js'
                import connectDB from './config/db.js'
                
                dotenv.config()
                
                connectDB()
                
                const importData = async()=>{
                try{
                    await Order.deleteMany()
                    await Product.deleteMany()
                    await User.deleteMany()
                
                    const createdUsers = await User.insertMany(users)
                    const adiminUser = createdUsers[0]._id
                
                    sampleProducts = products.map(product =>{
                        return {...product, user:adiminUser }
                    })
                    await Product.insertMany(sampleProducts)
                
                    console.log('Data Imported!'.green.inverse)
                    process.exit()      //success and exit
                
                }catch(error){
                    consolele.log(`${error}`.red.inverse)
                    process.exit(1)   //error and exit
                
                }
                
                }
                

                所以这里我在数据库和尝试块中填充一些集合,如果我没有收到任何错误,那么我们会以成功消息退出它,因此我们使用 process.exit() 参数中没有任何内容。 如果出现错误,那么我们需要退出并显示不成功的消息,因此我们在参数中传递 1,例如 process.exit(1)。

                extra:这里的退出是指退出典型的 node js 程序。例如,如果此代码位于名为 dbOperations.js 的文件中,则 process.exit 将退出并且不会运行 process.exit 之后的任何代码

                【讨论】:

                  【解决方案21】:

                  添加

                  process.exit(1);
                  

                  会为你解决问题

                  【讨论】:

                    【解决方案22】:

                    ctrl+C 终止当前进程
                    ctrl+C 两次退出REPL shell
                    ctrl+c 退出REPL SHELL

                    【讨论】:

                      猜你喜欢
                      • 2020-04-30
                      • 1970-01-01
                      • 2015-11-24
                      • 2015-01-29
                      • 2017-07-28
                      • 1970-01-01
                      • 2016-10-23
                      • 2011-09-20
                      相关资源
                      最近更新 更多