使用Windows PowerShell传递Node.js环境变量

Eve*_*tos 14 javascript windows powershell node.js

我正在尝试使用PowerShell将环境变量传递给Node.js:

C:\Users\everton\my-project> $env:MY_VAR = 8000 node index.js
Run Code Online (Sandbox Code Playgroud)

但是我在PowerShell中遇到错误:

令牌'节点'意外表达或声明

Har*_*nan 18

首先设置环境变量MY_VAR并像这样运行你的应用程序:

C:\Users\everton\my-project> $env:MY_VAR="8000" ; node index.js
Run Code Online (Sandbox Code Playgroud)

您可以访问环境变量MY_VAR里面index.js通过

process.env.MY_VAR
Run Code Online (Sandbox Code Playgroud)

注意:PowerShell不直接支持命令范围的环境变量.以上命令为该PowerShell会话设置环境变量.

  • 这为整个"bash"会话设置了命令,这不是命令作用域 (4认同)
  • 确实如此,而且值得一提。还值得一提的是我之前的评论。想象一下有人来这里寻找生产环境的解决方案。他运行您的命令来排除故障,并使用“NODE_ENV=dev”运行他的命令来获取 node.js 跟踪。他修复了问题,然后使用“node index.js”重新启动了服务器。只是他不知道自己仍然处于“NODE_ENV=dev”状态,并且在他的网站上的每个页面视图上增加了 500 毫秒的延迟。合理的答案是“PowerShell 无法做到这一点,请使用正确的工具或像这样的解决方法” (2认同)

mkl*_*nt0 7

注意:如果您可以假设Node.js已经安装 - 根据定义,调用时就是这种情况node- 考虑使用npm帮助程序包,如Cyril CHAPON 的有用答案所示
答案侧重于 PowerShell 中的通用解决方案

tl;博士

# Set env. variable temporarily, invoke the external utility, remove / restore old value.
$oldVal, $env:MYVAR = $env:MYVAR, 8000; node index.js; $env:MYVAR = $oldVal

# More structured alternative that uses a local variable.
& { $oldVal, $env:MY_VAR = $env:MY_VAR, 8000; node index.js; $env:MY_VAR = $oldVal }
Run Code Online (Sandbox Code Playgroud)

更简单地说,如果没有MY_VAR必须恢复的先前存在的价值。

$env:MYVAR=8000; node index.js; $env:MYVAR=$null

# More structured alternative
& { $env:MY_VAR=8000; node index.js; $env:MY_VAR=$null }
Run Code Online (Sandbox Code Playgroud)

请参阅下面的解释和基于辅助函数的替代方法。


为了补充哈里克里希南的有效答案

PowerShell没有等效于POSIX 类 shell 提供的传递环境变量的命令范围方法(从 PowerShell v7 开始 - 但是,将其引入 PowerShell - 不一定使用相同的语法 - 正在此 GitHub 问题中讨论);例如:

# Set env. variable temporarily, invoke the external utility, remove / restore old value.
$oldVal, $env:MYVAR = $env:MYVAR, 8000; node index.js; $env:MYVAR = $oldVal

# More structured alternative that uses a local variable.
& { $oldVal, $env:MY_VAR = $env:MY_VAR, 8000; node index.js; $env:MY_VAR = $oldVal }
Run Code Online (Sandbox Code Playgroud)

在PowerShell中,作为哈克里希纳恩的回答表明,你必须定义环境变量第一,然后在另一份声明中,调用外部程序,所以$env:MY_VAR="8000"; node index.js 正确的PowerShell的解决方案,但它是没有价值的是$env:MY_VAR 停留在范围其余部分该会话(它被设置在工艺水平)。

请注意,即使使用调用的脚本块&来创建子作用域也无济于事,因为此类子作用域仅适用于PowerShell变量,而不适用于环境变量。

当然,您可以调用后手动删除环境变量node:
Remove-Item env:MY_VAR或者甚至只是$env:MY_VAR = $null,这是顶部的第一个命令显示的内容。


一种更结构化的替代方案- 在设置多个环境变量和/或调用多个命令的情况下可能更好- 是使用通过以下方式调用的脚本块&

& { $oldVal, $env:MY_VAR = $env:MY_VAR, 8000; node index.js; $env:MY_VAR = $oldVal }
Run Code Online (Sandbox Code Playgroud)

这利用了:

  • { ... }是一个脚本块,为其中的命令提供清晰可见的分组;用 调用&,它会创建一个局部作用域,以便辅助变量$oldVal在退出块时自动超出作用域。

  • $oldVal, $env:MY_VAR = $env:MY_VAR, 8000在将值更改为$env:MY_VAR$oldVal同时保存in的旧值(如果有)8000;这种同时分配给多个变量的技术(在某些语言中称为解构分配)在Get-Help about_Assignment_Operators“分配多个变量”一节中进行了解释。

或者,使用下面辅助函数,或使用一种try { ... } finally { ... }方法,如我的这个相关答案中所示。


用于命令范围环境修改的辅助函数。

如果您定义下面的辅助函数(请记住,函数定义必须在调用之前放置),您可以实现对环境的命令范围修改,如下所示:

# Invoke `node index.js` with a *temporarily* set MY_VAR environment variable.
Invoke-WithEnvironment @{ MY_VAR = 8000 } { node index.js }
Run Code Online (Sandbox Code Playgroud)

Invoke-WithEnvironment() 源代码

function Invoke-WithEnvironment {
<#
.SYNOPSIS
Invokes commands with a temporarily modified environment.

.DESCRIPTION
Modifies environment variables temporarily based on a hashtable of values,
invokes the specified script block, then restores the previous environment.

.PARAMETER Environment
A hashtable that defines the temporary environment-variable values.
Assign $null to (temporarily) remove an environment variable that is
currently set.

.PARAMETER ScriptBlock
The command(s) to execute with the temporarily modified environment.

.EXAMPLE
> Invoke-WithEnvironment @{ PORT=8080 } { node index.js }

Runs node with environment variable PORT temporarily set to 8080, with its
previous value, if any 
#>
  param(
    [Parameter(Mandatory)] [System.Collections.IDictionary] $Environment,
    [Parameter(Mandatory)] [scriptblock] $ScriptBlock
  )
  # Modify the environment based on the hashtable and save the original 
  # one for later restoration.
  $htOrgEnv = @{}
  foreach ($kv in $Environment.GetEnumerator()) {
    $htOrgEnv[$kv.Key] = (Get-Item -EA SilentlyContinue "env:$($kv.Key)").Value
    Set-Item "env:$($kv.Key)" $kv.Value
  }
  # Invoke the script block
  try {
    & $ScriptBlock
  } finally {
    # Restore the original environment.
    foreach ($kv in $Environment.GetEnumerator()) {
      # Note: setting an environment var. to $null or '' *removes* it.
      Set-Item "env:$($kv.Key)" $htOrgEnv[$kv.Key]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Cyr*_*PON 6

我的答案要求使用Node.js和npm库。

...或者您只是费解编写晦涩的WTF语言脚本,然后使用命令范围(加上跨平台)的Node.js脚本之一: