node.js - 为什么我无法更新 Node js中的环境变量

标签 node.js node-modules

我想更新 Node js中的环境变量,但我无法更新其环境变量,我尝试使用 console.log(process.env.DB_HOST) 但仍然得到旧值,在这里我添加了我的整个代码,任何人都可以查看它,并帮助我解决这个问题,

function exec_api() { 
    return new Promise(async function (resolve) {
        const execSync = require('child_process').exec;
        //let child_process_obj = execSync('DB_HOST='+process.env.UNITTEST_DB_HOST+' DB_DATABASE='+process.env.UNITTEST_DB_DATABASE+'  DB_USERNAME='+process.env.UNITTEST_DB_USERNAME+' DB_PASSWORD='+process.env.UNITTEST_DB_PASSWORD+'  PORT='+process.env.UNITTEST_SERVICE_PORT+' ./node_modules/.bin/nodemon main.js'); 
        await execSync('export DB_HOST=' + process.env.UNITTEST_DB_HOST);
        await execSync('export DB_DATABASE=' + process.env.UNITTEST_DB_DATABASE);
        await execSync('export DB_USERNAME=' + process.env.UNITTEST_DB_USERNAME);
        await execSync('export DB_PASSWORD=' + process.env.UNITTEST_DB_PASSWORD);
        await execSync('export PORT=' + process.env.UNITTEST_API_BACKEND_PORT);
        let child_process_obj = await execSync('node main.js');
        unittest_api_backend_process_id = child_process_obj.pid;
        resolve(true);
    });
}

最佳答案

TLDR:只需更改 process.env

要更改、添加或删除环境变量,请使用process.env。以下是显示其工作原理的测试代码:

ma​​in.js中:

console.log(process.env.DB_DATABASE);

exec.js中:

const execSync = require ('child_process').execSync;

process.env.DB_DATABASE = 'foo'; // this is ALL you need to do

console.log(execSync('node main.js').toString('utf8'));

对于上面的两个文件,如果运行 node exec.js,您将在控制台中看到 foo 打印出来。这是从 main.js 打印的,它继承了 exec.js 的环境。

因此您需要在代码中执行以下操作:

我想更新 Node js中的环境变量,但我无法更新其环境变量,我尝试使用console.log(process.env.DB_HOST),但我仍然得到旧值,在这里我添加了我的整个代码,任何人都可以查看它,并帮助我解决这个问题,

function exec_api() { 
    return new Promise(function (resolve) {
        const exec = require('child_process').exec;

        // The following is node.js equivalent of bash "export":
        process.env.DB_HOST = process.env.UNITTEST_DB_HOST;
        process.env.DB_DATABASE = process.env.UNITTEST_DB_DATABASE;
        process.env.DB_USERNAME = process.env.UNITTEST_DB_USERNAME;
        process.env.DB_PASSWORD = process.env.UNITTEST_DB_PASSWORD;
        process.env.PORT = process.env.UNITTEST_SERVICE_PORT;

        let child_process_obj = exec('node main.js', {
            stdio: ['inherit', 'inherit', 'inherit']
        });

        unittest_api_backend_process_id = child_process_obj.pid;

        resolve(true);
    });
}

请注意,如果您希望在 main.js 结束时返回 Promise,您需要执行以下操作:

function exec_api() { 
    return new Promise(function (resolve) {
        const exec = require('child_process').exec;

        // The following is node.js equivalent of bash "export":
        process.env.DB_HOST = process.env.UNITTEST_DB_HOST;
        process.env.DB_DATABASE = process.env.UNITTEST_DB_DATABASE;
        process.env.DB_USERNAME = process.env.UNITTEST_DB_USERNAME;
        process.env.DB_PASSWORD = process.env.UNITTEST_DB_PASSWORD;
        process.env.PORT = process.env.UNITTEST_SERVICE_PORT;

        let child_process_obj = exec('node main.js', {
            stdio: ['inherit', 'inherit', 'inherit']
        });

        unittest_api_backend_process_id = child_process_obj.pid;

        child_process_obj.on('exit', () => resolve(true));

        // ^^^ Cannot use `await` as the API is not promise based
        //     but event based instead.
    });
}
<小时/>

长话短说:为什么导出不起作用的完整解释

在unixen上,环境变量,甚至包括当前工作目录、根目录(可以通过chroot更改)等在内的整个环境都不是shell的功能。它们是流程的特征。

我们可能熟悉某些 shell 的 export 语法,用于为子进程设置环境变量,但这就是 shell 的语法。它与环境变量本身无关。例如,C/C++ 不使用 export 而是使用 setenv()函数确实设置了环境变量(事实上,这就是 bash/sh/ksh 等在实现导出时在内部所做的事情)。

在node.js中,读取和设置环境变量的机制是通过process.env实现的。

为什么要求 shell 执行此操作不起作用

这不仅仅是一个 Node.js 问题。它在 bash 中也不起作用:

exporter.sh中:

#! /bin/bash

export DB_DATABASE=$1

exec.sh中:

#! /bin/bash

./exporter.sh foo
echo $DB_DATABASE ;# does not print "foo"

这是 unixen 的核心安全功能:不应允许其他用户扰乱您的进程。在环境情况下执行此策略的方式是,只有父进程可以设置子进程的环境。子进程不允许设置父进程的环境。假设子进程属于父进程,因此您应该被允许对程序执行您想要的操作 - 但由于父进程(您)不属于子进程,因此不允许 child 破坏 parent 的环境。

这就是您尝试使用导出不起作用的原因。它确实有效(变量确实是在子 shell 中创建的),但不允许更改其父进程(node.js 进程)的环境

关于node.js - 为什么我无法更新 Node js中的环境变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58425890/

相关文章:

javascript - 如何在不丢失数据的情况下将 POST 正文数据传递到另一条路线?

javascript - 开 Jest : Cannot spy the property because it is not a function; undefined given instead getting error while executing my test cases

javascript - 如何从 .html 页面链接到 .ejs 页面?

node.js - npm global install 给出 EISDIR 警告和 ENOENT 错误

node.js - 如何将图像插入 CouchDB

javascript - 在javascript中实现递归

即使存在,PhpStorm 也无法解析包导入(react-router-dom)

reactjs - 如何防止(卸载)TypeScript 安装并将它自己的 @types 引用到 AppData\Local

node.js - 从回调中设置全局变量

node.js - `sass-loader` 需要 `node-sass` >=4。请安装兼容版本