web-dev-qa-db-ja.com

Windows PowerShellでNode.js環境変数を渡す

次のように、PowerShellを使用して環境変数をNode.jsに渡そうとしています。

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

しかし、PowerShellでエラーが発生します。

トークン「ノード」の予期しない式またはステートメント

14
Everton Santos

最初に環境変数MY_VARを設定し、次のようにアプリを実行します。

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

MY_VAR内の環境変数index.jsにアクセスできます

process.env.MY_VAR

注:PowerShellは、コマンドスコープの環境変数を直接サポートしていません。上記のコマンドは、そのPowerShellセッションの環境変数を設定します。

18
Harikrishnan

私の答えは、Node.jsおよびnpmライブラリの使用を必要とします。

...または、obscure-WTF-language-scriptingを書く手間を省き、コマンドスコープ(およびクロスプラットフォーム)のNode.jsスクリプトのいずれかを使用します。

  • cross-env (インライン用)

    cross-env MYVAR=MYVALUE node index.js
    
  • env-cmd (.envファイルから)

    env-cmd .env node index.js
    

    #.env file
    MYVAR=MYVALUE
    
7
Cyril CHAPON

注:Node.jsがすでにインストールされていると想定できる場合-定義により、nodeを呼び出すときのケースとして Cyril CHAPON 'に示すように、npmヘルパーパッケージの使用を検討してください。 s役立つ答え
これ回答は、PowerShell内の一般的なソリューションに焦点を当てています。

tl; dr

_# 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のようなシェルが提供する環境変数を渡すコマンドスコープメソッドと同等のnoメソッドがあります(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_ isは適切なPowerShellソリューションですが、_$env:MY_VAR_ スコープ内に留まるセッションの残り(プロセスレベルで設定されます)。

このような子スコープはPowerShell変数にのみ適用され、環境変数には適用されないため、_&_で呼び出されたスクリプトブロックを使用して子スコープを作成しても役に立たないことに注意してください。

もちろん、環境変数を削除することができます後で手動でnode call
_Remove-Item env:MY_VAR_または_$env:MY_VAR = $null_でさえ、これは上部の最初のコマンドが示すものです。


より構造化された代替案-multiple環境変数を設定する場合や複数のコマンドを呼び出す場合におそらくより良い-_&_で呼び出されるスクリプトブロックを使用する:

_& { $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_ のセクション「複数の変数の割り当て」で説明しています。

Alternatively、以下のhelper関数を使用する、または_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]
    }
  }
}
_
5
mklement0