Как создать постоянную переменную среды для Linux в PowerShell

Как создать, установить и обновить постоянную переменную среды для Linux в PowerShell Core. Следующее решение работает правильно, но только когда я запускаю скрипт в Windows:

[Environment]::SetEnvironmentVariable("Variable", "Value", "Machine")

1 ответ

Я добавил поддержку в свойxEnvironmentVariables Модуль PowerShell для этого. Фактическая функция PowerShell находится по адресу: Set-NixEnvironmentVariable.ps1 . Ниже приведена рабочая версия функции. YMMV, бегите с осторожностью. Это работает только при запуске из повышенного состояния (su) какetc/environmentфайл защищен.

      function Set-EnvironmentVariable {
  param(
    [Parameter(Mandatory = $true)]
    [string]$Name,
    [Parameter(Mandatory = $true)]
    [string]$Value
  )
  begin {
    Write-Debug "[Begin Set-NixEnvironmentVariable]"
    $environmentFile = "/etc/environment"

    #region functions

    # function to test for root

    function Test-Root {
      $isRoot = $false
      $userId = . id -u
      if ($userId -eq 0) {
        $isRoot = $true
      }
      return $isRoot
    }

    # function to parse te environment file

    function Read-EnvironmentFile {
      param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$EnvironmentFile
      )
      $environmentVariables = [System.Collections.Specialized.OrderedDictionary]::new()
      $environmentFileContent = Get-Content -Path $EnvironmentFile
      foreach ($line in $environmentFileContent) {
        if ($line -match "^(?<name>[A-Z_]+)=(?<value>.*)$") {
          $environmentVariables.Add($matches.name, $matches.value)
          # $environmentVariables[$matches.name] = $matches.value
        }
      }
      return $environmentVariables
    }

    # function to convert a hashtable to a valid environment file

    function ConvertTo-EnvironmentFile {
      [CmdletBinding()]
      param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [System.Collections.Specialized.OrderedDictionary]$EnvironmentVariables
      )
      $stringBuilder = [System.Text.StringBuilder]::new()
      # iterate over the keys in the order they are listed in the ordered dictionary, and add the resulting environment file content to the string builder
      foreach ($key in $EnvironmentVariables.Keys) {
        $null = $stringBuilder.AppendLine("$key=$($EnvironmentVariables[$key])")
      }
      return $stringBuilder.ToString()
      # foreach ($key in $EnvironmentVariables.Keys) {
      #   $environmentFileContent += "$key=$($EnvironmentVariables[$key])"
      # }
      # return $environmentFileContent
    }

    # function to test if the environment variable already exists

    function Test-EnvironmentVariableExists {
      [CmdletBinding()]
      param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$EnvironmentFile,
        [Parameter(Mandatory = $true)]
        [string]$Name
      )
      $environmentFileContent = Get-Content -Path $EnvironmentFile
      foreach ($line in $environmentFileContent) {
        if ($line -match "^(?<name>[A-Z_]+)=(?<value>.*)$") {
          if ($matches.name -eq $Name) {
            Write-Warning "The environment variable $Name already exists in $EnvironmentFile"
            return $true
          }
        }
      }
      return $false
    }

    # function to add the environment variable to the environment file

    function Add-EnvironmentVariable {
      [CmdletBinding()]
      param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$EnvironmentFile,
        [Parameter(Mandatory = $true)]
        [string]$Name,
        [Parameter(Mandatory = $true)]
        [string]$Value
      )
      $environmentFileContent = Get-Content -Path $EnvironmentFile
      $environmentFileContent += "`n$Name=$Value"
      Set-Content -Path $EnvironmentFile -Value $environmentFileContent
    }

    # function to update the environment variable in the environment file

    function Update-EnvironmentVariable {
      [CmdletBinding()]
      param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$EnvironmentFile,
        [Parameter(Mandatory = $true)]
        [string]$Name,
        [Parameter(Mandatory = $true)]
        [string]$Value
      )
      $environmentFileContent = Get-Content -Path $EnvironmentFile
      foreach ($line in $environmentFileContent) {
        if ($line -match "^(?<name>[A-Z_]+)=(?<value>.*)$") {
          if ($matches.name -eq $Name) {
            $line = "$Name=$Value"
          }
        }
      }
      Set-Content -Path $EnvironmentFile -Value $environmentFileContent
    }


    # a function to check the differences between two environment files

    function Compare-EnvironmentFiles {
      [CmdletBinding()]
      param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$EnvironmentFile1,
        [Parameter(Mandatory = $true)]
        [string]$EnvironmentFile2
      )
      $environmentFile1Content = Get-Content -Path $EnvironmentFile1
      $environmentFile2Content = Get-Content -Path $EnvironmentFile2
      $environmentFile1Content | Compare-Object -ReferenceObject $environmentFile2Content
    }


    #endregion functions

    if (!(Test-Root)) {
      Write-Error "This script must be run as root"
      break
    }
    # create a backup in the user's home directory
    $backupFile = "$ENV:HOME/environment.bak"
    try {
      Copy-Item -Path $environmentFile -Destination $backupFile -Force
    } catch {
      Write-Warning "Unable to create backup of $environmentFile"
      break
    }

    # read the environment file into an ordered dictionary
    $environmentVariables = Read-EnvironmentFile -EnvironmentFile $environmentFile

    # test if the environment variable already exists

    $environmentVariableExists = Test-EnvironmentVariableExists -EnvironmentFile $environmentFile -Name $Name

  }
  process {
    Write-Debug "[Process Set-NixEnvironmentVariable]"
    # if the environment variable already exists, update it
    if ($environmentVariableExists) {
      try {
        Update-EnvironmentVariable -EnvironmentFile $environmentFile -Name $Name -Value $Value
      } catch {
        Write-Warning "Unable to update environment variable $Name in $environmentFile"
        Write-Warning $PSItem.Exception.Message
        Write-Warning "if the environment variable is not set correctly, you can restore the backup file at $backupFile"
        break
      }
    } else {
      # if the environment variable does not exist, add it
      try {
        Add-EnvironmentVariable -EnvironmentFile $environmentFile -Name $Name -Value $Value

      } catch {
        Write-Warning "Unable to add environment variable $Name in $environmentFile"
        Write-Warning $PSItem.Exception.Message
        Write-Warning "if the environment variable is not set correctly, you can restore the backup file at $backupFile"
        break
      }
    }


  }
  end {
    Write-Debug "[End Set-NixEnvironmentVariable]"
    # clean up backup file if the only difference is the new variable
    $differences = Compare-EnvironmentFiles -EnvironmentFile1 $environmentFile -EnvironmentFile2 $backupFile
    if ($differences.Count -eq 1) {
      Remove-Item -Path $backupFile
    } else {
      Write-Warning "The environment file $environmentFile has been updated"
      Write-Warning "if the environment variable is not set correctly, you can restore the backup file at $backupFile"
    }
  }

}

Другие вопросы по тегам