Передайте переменную среды Node.js в Windows PowerShell

Я пытаюсь передать переменную среды в Node.js с помощью PowerShell следующим образом:

C:\Users\everton\my-project> $env:MY_VAR = 8000 node index.js

Но я получаю сообщение об ошибке в PowerShell:

Токен 'узел' неожиданное выражение или утверждение

Ответ 1

MY_VAR установите переменную среды MY_VAR и запустите ваше приложение следующим образом:

C:\Users\everton\my-project> $env:MY_VAR="8000" ; node index.js

Вы можете получить доступ к переменной окружения MY_VAR внутри index.js помощью

process.env.MY_VAR

Примечание. PowerShell напрямую не поддерживает переменные среды области действия команды. Приведенная выше команда устанавливает переменную среды для этого сеанса PowerShell.

Ответ 2

Мой ответ требует использования библиотек Node.js и npm.

... или вы просто избавляетесь от написания сценариев с непонятным WTF-языком и используете один из сценариев Node.js для области команд (плюс кроссплатформенный):

  • cross-env (для встроенного)

    cross-env MYVAR=MYVALUE node index.js
    
  • env-cmd (из файла .env)

    env-cmd .env node index.js
    

    с

    #.env file
    MYVAR=MYVALUE
    

Ответ 3

Note: If you can assume that Node.js is already installed - as is by definition the case when you're invoking [TG40] - consider use of [TG41] helper packages, as shown in Cyril CHAPON helpful answer.
This answer focuses on generic solutions from within PowerShell.

ТЛ; др

# 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 }

Проще говоря, если нет ранее существовавшего значения 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 }

См. ниже объяснение и альтернативу на основе вспомогательной функции.


В дополнение к эффективному ответу Харикришнана:

PowerShell не имеет эквивалента для метода передачи команд среды передачи, который предлагает POSIX-подобная оболочка (начиная с PowerShell v7 - однако его введение в PowerShell - не обязательно с тем же синтаксисом) обсуждается в это проблема GitHub); например.:

 # E.g., in *Bash*: 
 # Define environment variable MY_VAR for the child process being invoked ('node')
 # ONLY; in other words: MY_VAR is scoped to the command being invoked
 # (subsequent commands do not see it).
 MY_VAR=8000 node index.js

В PowerShell, как показывает ответ харикришнана, сначала нужно определить переменную среды, а затем в отдельном выражении вызвать внешнюю программу, поэтому $env:MY_VAR="8000"; node index.js является правильным решением PowerShell, но ничего не стоит, чтобы $env:MY_VAR оставалось в области для оставшейся части сеанса (это установлено на уровне процесса).

Обратите внимание, что даже использование блока сценария, вызванного с помощью & для создания дочерней области, здесь не помогает, поскольку такие дочерние области применяются только к переменным PowerShell, а не к переменным среды.

Конечно, вы можете удалить переменную среды вручную после вызова node:
Remove-Item env:MY_VAR или даже просто $env:MY_VAR = $null, это то, что показывает 1-я команда сверху.


Более структурированная альтернатива - возможно, лучше в случае установки нескольких переменных среды и/или вызова нескольких команд - заключается в использовании блока сценария, вызываемого с помощью &:

& { $oldVal, $env:MY_VAR = $env:MY_VAR, 8000; node index.js; $env:MY_VAR = $oldVal }

Это использует преимущества:

  • { ... } - блок сценариев, который обеспечивает четко видимую группировку для команд в нем; вызывается с помощью &, создает локальную область видимости, поэтому вспомогательная переменная $oldVal автоматически выходит из области действия при выходе из блока.

  • $oldVal, $env:MY_VAR = $env:MY_VAR, 8000 сохраняет старое значение (если оно есть) из $env:MY_VAR в $oldVal при изменении значения на 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 }

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]
    }
  }
}