W systemie Linux mogę:
$ FOO=BAR ./myscript
aby wywołać „myscript” z ustawioną zmienną środowiskową FOO.
Czy coś podobnego jest możliwe w PowerShell, tj. Bez konieczności wcześniejszego ustawiania zmiennej, wywoływania polecenia, a następnie ponownego kasowania zmiennej?
Żeby wyjaśnić mój przypadek użycia - nie chcę tego używać jako części skryptu. Mam raczej skrypt innej firmy, którego zachowanie mogę kontrolować za pomocą zmiennych środowiskowych, ale w tym przypadku nie za pomocą argumentów wiersza poleceń. Możliwość przełączania się między pisaniem
$ OPTION=1 ./myscript
i
$ ./myscript
byłoby po prostu bardzo przydatne.
Odpowiedzi:
Generalnie lepiej byłoby przekazywać informacje do skryptu za pomocą parametru niż zmiennej globalnej (środowiskowej). Ale jeśli tego potrzebujesz, możesz to zrobić w ten sposób:
$env:FOO = 'BAR'; ./myscript
Zmienną środowiskową $ env: FOO można później usunąć w następujący sposób:
źródło
env:foo
przywracać starej wartości (być może nieustawionej) zamiast ją usuwać?& {$pre = $env:foo; $env:foo = 'bar'; ./myscript; if ($pre) {$env:foo = $pre} else {Remove-Item env:\foo}
... niektórzy mogą powiedzieć , że są nieporęczni , ale unikną skutków ubocznych ...Ten problem zmotywował mnie na tyle, że zacząłem pisać scenariusz: with-env.ps1
Stosowanie:
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
Z drugiej strony, jeśli zainstalujesz Gow , możesz użyć,
env.exe
który może być nieco bardziej niezawodny niż szybki skrypt, który napisałem powyżej.Stosowanie:
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
źródło
2 proste sposoby na zrobienie tego w jednej linii:
$env:FOO='BAR'; .\myscript; $env:FOO='' $env:FOO='BAR'; .\myscript; Remove-Item Env:\FOO
Po prostu podsumowałem informacje z innych odpowiedzi (dziękuję), które z jakiegoś powodu nie zawierają czystych linijek.
źródło
Aby uzyskać odpowiednik składni Uniksa, musisz nie tylko ustawić zmienną środowiskową, ale musisz zresetować ją do poprzedniej wartości po wykonaniu polecenia. Osiągnąłem to dla typowych poleceń, których używam, dodając funkcje podobne do poniższych do mojego profilu PowerShell.
function cmd_special() { $orig_master = $env:app_master $env:app_master = 'http://host.example.com' mycmd $args $env:app_master = $orig_master }
Więc
mycmd
jest jakiś plik wykonywalny, który działa inaczej w zależności od wartości zmiennej środowiskowejapp_master
. Definiująccmd_special
, mogę teraz wykonywaćcmd_special
z wiersza poleceń (w tym inne parametry) zapp_master
ustawioną zmienną środowiskową ... i zostaje zresetowana (lub nawet wyłączona) po wykonaniu polecenia.Przypuszczalnie mógłbyś również zrobić to ad hoc dla pojedynczego wywołania.
& { $orig_master = $env:appmaster; $env:app_master = 'http://host.example.com'; mycmd $args; $env:app_master = $orig_master }
To naprawdę powinno być łatwiejsze niż to, ale najwyraźniej nie jest to przypadek użycia, który jest łatwo obsługiwany przez PowerShell. Może przyszła wersja (lub funkcja innej firmy) ułatwi ten przypadek użycia. Byłoby miło, gdyby PowerShell miał cmdlet, który robiłby to, np:
with-env app_master='http://host.example.com' mycmd
Być może guru PowerShell może zasugerować, jak można napisać takie polecenie cmdlet.
źródło
Biorąc pod uwagę, że CMD jest natywnym interfejsem wiersza polecenia w jądrze systemu Windows (i nadal jest interfejsem automatyzacji dla wielu narzędzi), możesz wykonywać skrypt PowerShell za
powershell.exe
pomocą wiersza polecenia CMD lub interfejsu, który akceptuje instrukcje konsoli CMD.Jeśli używasz
-File
parametru do przekazania skryptupowershell.exe
, żaden inny kod PowerShell nie może być użyty do ustawienia zmiennej środowiskowej, do której ma dostęp skrypt, więc zamiast tego możesz ustawić zmienne środowiskowe w środowisku CMD przed wywołaniempowershell.exe
:> set foo=bar && powershell.exe -File .\script.ps1
Pojedynczy
&
również zadziała, ale pozwoli na kontynuowanie polecenia, jeśli zset
jakiegoś powodu się nie powiedzie. (Czy to w ogóle możliwe? Nie mam pojęcia.)Poza tym bezpieczniejsze może być zawijanie
"foo=bar"
cudzysłowów, tak aby nic po nim nie było przekazywaneset
jako zawartość zmiennej.źródło
Zakres zmiennych można przypisać do funkcji i skryptów.
$script:foo = "foo" $foo $function:functionVariable = "v" $functionVariable
Nowa-zmienna ma również parametr -scope, jeśli chcesz być formalny i zadeklarować zmienną za pomocą nowej-zmiennej.
źródło
https://gist.github.com/bobalob/6632690e33747c13a8c00875ee686be2
$ENV:ARM_SUBSCRIPTION_ID = "" $ENV:ARM_CLIENT_ID = "" $ENV:ARM_CLIENT_SECRET = "" # This should end with an '=' symbol $ENV:ARM_TENANT_ID = ""
źródło