【问题标题】:How do I set an env variable in PowerShell if it doesn't exist?如果 PowerShell 中的环境变量不存在,如何设置它?
【发布时间】:2016-12-20 01:55:52
【问题描述】:

我很惊讶在谷歌搜索了一段时间后我没有得到这个常见场景的答案......

如果环境变量不存在,如何在PowerShell中设置?

【问题讨论】:

    标签: powershell environment-variables


    【解决方案1】:

    以下代码为当前进程定义环境变量FOO,如果它还不存在的话。

    if ($null -eq $env:FOO) { $env:FOO = 'bar' }
    
    # Alternatively:
    if (-not (Test-Path env:FOO)) { $env:FOO = 'bar' }
    

    在具有null-coalescing operatorsPowerShell (Core) 7.1+中,您可以简化为:

    $env:FOO ??= 'bar'
    

    注意:根据定义,环境变量是字符串。如果给定环境变量定义,但没有值,它的值是空字符串 ('') 而不是$null .因此,与$null 比较可用于区分未定义 环境变量和已定义但没有值 的环境变量。但是,请注意分配到环境变量在 PowerShell / .NET没有区分 $null'',以及 任何一个值都会导致取消定义(删除)目标环境变量。

    注意:如果环境变量是由上面的赋值($env:FOO = ...)按需创建的,它将存在于当前进程和它创建的任何子进程 仅限 谢谢PetSerAl


    以下内容主要由Ansgar Wiechers提供,Mathias R. Jessen补充:

    Windows[*] 上,如果您想定义环境变量永久,需要使用[System.Environment]类的静态SetEnvironmentVariable()方法:

    # user environment
    [Environment]::SetEnvironmentVariable('FOO', 'bar', 'User')
    
    # system environment (requires admin privileges)
    [Environment]::SetEnvironmentVariable('FOO', 'bar', 'Machine')
    

    请注意,这些定义在未来会话(进程)中生效,因此为了当前进程定义变量也是如此,运行$env:FOO = 'bar' 另外,这实际上与[Environment]::SetEnvironmentVariable('FOO', 'bar', 'Process') 相同。

    [Environment]::SetEnvironmentVariable()UserMachine 一起使用时,会向其他应用程序发送WM_SETTINGCHANGE 消息以通知它们更改(尽管很少有应用程序对此类通知做出反应)。
    这不适用于定位Process(或分配给$env:FOO)时,因为无论如何其他应用程序(进程)都无法看到该变量。

    See also.


    [*] 在类似 Unix 的平台上,针对持久作用域 UserMachine 的尝试会被悄悄忽略,从 .NET (Core) 5 开始,这 鉴于缺乏跨 Unix 平台的统一机制,不支持定义持久性环境变量不太可能改变。

    【讨论】:

      【解决方案2】:

      代码

      function Set-LocalEnvironmentVariable {
          param (
              [Parameter()]
              [System.String]
              $Name,
      
              [Parameter()]
              [System.String]
              $Value,
      
              [Parameter()]
              [Switch]
              $Append
          )
          if($Append.IsPresent)
          {
              if(Test-Path "env:$Name")
              {
                  $Value = (Get-Item "env:$Name").Value + $Value
              }
          }
          Set-Item env:$Name -Value "$value" | Out-Null
      }
      
      function Set-PersistentEnvironmentVariable {
          param (
              [Parameter()]
              [System.String]
              $Name,
          
              [Parameter()]
              [System.String]
              $Value,
          
              [Parameter()]
              [Switch]
              $Append        
          )
          
          Set-LocalEnvironmentVariable -Name $Name -Value $Value -Append:$Append
          if ($Append.IsPresent) {
              $value = (Get-Item "env:$Name").Value
          }
          
          if ($IsWindows) {
              setx "$Name" "$Value" | Out-Null
              return
          }
          $pattern = "\s*export[ \t]+$Name=[\w]*[ \t]*>[ \t]*\/dev\/null[ \t]*;[ \t]*#[ \t]*$Name\s*"
          
          if ($IsLinux) {
              $file = "~/.bash_profile"
              $content = (Get-Content "$file" -ErrorAction Ignore -Raw) + [System.String]::Empty
              $content = [System.Text.RegularExpressions.Regex]::Replace($content, $pattern, [String]::Empty);
              $content += [System.Environment]::NewLine + [System.Environment]::NewLine + "export $Name=$Value > /dev/null ;  # $Name"
              Set-Content "$file" -Value $content -Force
              return
          }
          if ($IsMacOS) {
              $file = "~/.zprofile"
              $content = (Get-Content "$file" -ErrorAction Ignore -Raw) + [System.String]::Empty
              $content = [System.Text.RegularExpressions.Regex]::Replace($content, $pattern, [String]::Empty);
              $content += [System.Environment]::NewLine + [System.Environment]::NewLine + "export $Name=$Value > /dev/null ;  # $Name"
              Set-Content "$file" -Value $content -Force
              return
          }
          throw "Invalid platform."
      }
      

      • 函数 Set-PersistentEnvironmentVariable 在实际过程和系统中设置变量/值。该函数调用Set-LocalEnvironmentVariable函数来设置进程范围变量,并在机器范围内执行设置变量的任务。

      在 Windows 上您可以使用:

      在 Linux 上,我们可以将 export VARIABLE_NAME=Variable value 添加到文件 ~/.bash_profile。对于新的 bash 终端,该进程执行位于 ~/.bash_profile 中的这些指令。

      在类似于 Linux 的 MacOS 上,但如果您有 zsh 终端,则文件为 .zprofile,如果默认终端为 bash,则该文件是 .bash_profile。在我的功能代码中,如果您愿意,我们需要添加对默认终端的检测。我假设默认终端是 zsh

      • 函数 Set-LocalEnvironmentVariable 在实际过程中设置变量/值。使用云端硬盘 env:

      示例

      #Set "Jo" value to variable "NameX", this value is accesible in current process and subprocesses, this value is accessible in new opened terminal.
      Set-PersistentEnvironmentVariable -Name "NameX" -Value "Jo"; Write-Host $env:NameX
      
      #Append value "ma" to current value of variable "NameX", this value is accesible in current process and subprocesses, this value is accessible in new opened terminal.
      Set-PersistentEnvironmentVariable -Name "NameX" -Value "ma" -Append; Write-Host $env:NameX
      
      #Set ".JomaProfile" value to variable "ProfileX", this value is accesible in current process/subprocess.
      Set-LocalEnvironmentVariable "ProfileX" ".JomaProfile"; Write-Host $env:ProfileX
      
      
      

      输出

      Windows 10

      Ubuntu WSL


      参考文献

      查看About Environment Variables
      Shell initialization files
      ZSH: .zprofile, .zshrc, .zlogin - What goes where?

      【讨论】:

        猜你喜欢
        • 2020-09-29
        • 2020-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-02
        • 2016-01-11
        • 2014-09-29
        相关资源
        最近更新 更多