Подтвердить что ты не робот

PowerShell: настройка переменной среды только для одной команды

На Linux я могу сделать:

$ FOO=BAR ./myscript

вызвать "myscript" с установленной переменной окружения FOO.

Возможно ли нечто подобное в PowerShell, то есть без необходимости сначала устанавливать переменную, вызывать команду, а затем снова сбрасывать переменную?

Чтобы быть более ясным в моем случае использования - я не хочу использовать это как часть сценария. Скорее, у меня есть сторонний скрипт, чьим поведением я могу управлять с помощью переменных окружения, но в данном случае это не аргументы командной строки. Таким образом, возможность чередовать между

$ OPTION=1 ./myscript

а также

$ ./myscript

было бы очень удобно.

4b9b3361

Ответ 1

Как правило, было бы лучше передавать информацию в сценарий с помощью параметра, а не глобальной переменной (среды). Но если это то, что вам нужно сделать, вы можете сделать это следующим образом:

$env:FOO = 'BAR'; ./myscript

Переменная среды $ env: FOO может быть удалена позже так:

Remove-Item Env:\FOO

Ответ 2

Чтобы выполнить эквивалент синтаксиса Unix, вам нужно не только установить переменную среды, но и сбросить ее прежнее значение после выполнения команды. Я выполнил это для общих команд, которые я использую, добавив в свой профиль PowerShell функции, аналогичные приведенным ниже.

function cmd_special()
{
  $orig_master = $env:app_master
  $env:app_master = 'http://host.example.com'
  mycmd $args
  $env:app_master = $orig_master
}

Таким образом, mycmd - это некоторый исполняемый файл, который работает по-разному в зависимости от значения переменной окружения app_master. Определив cmd_special, я теперь могу выполнить cmd_special из командной строки (включая другие параметры) с app_master переменной среды app_master... и она будет сброшена (или даже неустановлена) после выполнения команды.

Предположительно, вы также можете сделать это ad-hoc для одного вызова.

& { $orig_master = $env:appmaster; $env:app_master = 'http://host.example.com'; mycmd $args; $env:app_master = $orig_master }

Это действительно должно быть проще, чем это, но, очевидно, это не тот случай использования, который легко поддерживается PowerShell. Возможно, будущая версия (или сторонняя функция) облегчит этот вариант использования. Было бы неплохо, если бы PowerShell имел командлет, который бы делал это, например:

with-env app_master='http://host.example.com' mycmd

Возможно, гуру PowerShell может подсказать, как можно написать такой командлет.

Ответ 3

Я получил достаточно мотивированы об этой проблеме, что я пошел вперед и написал script для этого: с-env.ps1

Использование:

with-env.ps1 FOO=foo BAR=bar your command here

# Supports dot-env files as well
with-env.ps1 .\.env OTHER_ENV=env command here

С другой стороны, если вы установите Gow вы можете использовать env.exe, которые могли бы быть немного более надежным, чем быстрый script Я написал выше.

Использование:

env.exe FOO=foo BAR=bar your command here

# To use it with dot-env files
env.exe $(cat .env | grep.exe -v '^#') SOME_OTHER_ENV=val your command

Ответ 4

Учитывая, что CMD является собственным CLI в ядре Windows (и все еще является интерфейсом автоматизации для многих инструментов), вы, возможно, выполняете свой сценарий PowerShell с powershell.exe из приглашения CMD или интерфейсом, который принимает операторы консоли CMD.

Если вы используете параметр -File для передачи вашего сценария в powershell.exe, никакой другой код PowerShell нельзя использовать для установки переменной среды для доступа к сценарию, поэтому вместо этого вы можете установить переменные среды в среде CMD перед вызовом powershell.exe:

> set foo=bar && powershell.exe -File .\script.ps1

Один & также будет работать, но позволит команде продолжиться, если по какой-то причине произошел сбой set. (Возможно ли это? Я понятия не имею.)

Кроме того, может быть безопаснее заключить в кавычки "foo=bar" чтобы ничего не передавалось для set в качестве содержимого переменной.

Ответ 6

Вы можете использовать переменные области видимости для функций и скриптов.

$script:foo = "foo"
$foo
$function:functionVariable = "v"
$functionVariable

New-Variable также имеет параметр -scope, если вы хотите быть формальным и объявлять свою переменную с помощью новой переменной.