it-swarm.com.ru

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

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

$ FOO=BAR ./myscript

вызвать «myscript» с установленной переменной среды FOO.

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

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

$ OPTION=1 ./myscript

а также 

$ ./myscript

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

55
miracle2k

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

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

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

Remove-Item Env:\FOO
23
Keith Hill

Чтобы выполнить эквивалент синтаксиса 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 ... и она будет сброшена (или даже неустановлена) после выполнения команды.

Предположительно, вы также можете сделать это 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 может подсказать, как можно написать такой командлет.

2
Jason R. Coombs

Я был достаточно мотивирован об этой проблеме, поэтому я решил написать сценарий для нее: with-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, который может быть немного более надежным, чем быстрый скрипт, который я написал выше.

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

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
2
kizzx2

Учитывая, что 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 в качестве содержимого переменной.

0
NReilingh