2009-09-14 21 views
41

na Linuksie, co mogę zrobić:PowerShell: Ustawienie zmiennej środowiskowej za pomocą jednego polecenia tylko

$ FOO=BAR ./myscript 

nazwać „myscript” z otoczeniem zmienna FOO jest ustawiony.

Czy coś podobnego jest możliwe w Powershell, tj. Bez konieczności ustawiania pierwszej zmiennej, wywołaj polecenie, a następnie ponownie zresetuj zmienną?

Aby lepiej poznać mój przypadek użycia - nie chcę używać tego jako części skryptu. Mam raczej skrypt strony trzeciej, którego zachowanie mogę kontrolować za pomocą zmiennych środowiskowych, ale w tym przypadku nie z argumentów wiersza poleceń. Tak jest w stanie przełączać między wpisywanie

$ OPTION=1 ./myscript 

i

$ ./myscript 

będzie tylko bardzo poręczny.

+0

Chyba moje pytanie byłoby, dlaczego trzeba by to zrobić? Myślę, że istnieje lepsze rozwiązanie. – EBGreen

+6

To zwykle nie jest pomocne pytanie, @EBGreen. Fakt, że możliwości istnieją w powłokach systemu UNIX sugeruje, że jest w tym użyteczny. Z góry mojej głowy: kontrolowanie nazwy użytkownika i adresu e-mail git używa do zatwierdzenia. Dla nich nie ma opcji wiersza poleceń - musisz ustawić je w ~/.gitconfig, .git/config w każdym repozytorium lub envars. Z tych opcji, envars są wyraźnie łatwiejsze do ustawienia w locie (i wygodnie przesłonić wartości w plikach). Więc jeśli chcę zmienić nazwisko autora na "git commit" w powershell, jak to zrobić? –

Odpowiedz

-3

Możesz zmieniać zakres zmiennych 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 zadeklaruj swoją zmienną za pomocą nowej zmiennej.

+0

Hmmm ... Nie myśl, że ta odpowiedź ma zastosowanie tutaj. Zmienne PowerShell nie są zmiennymi środowiskowymi. W oparciu o to pytanie, osoba pytająca nie używa zmiennych środowiskowych jako przestrzeni na zarysowania (jak w CMD [gdyby tak było, ta odpowiedź miałaby zastosowanie]), ale musi manipulować środowiskiem przed wywołaniem zewnętrznego polecenia, a następnie przywrócić środowisko potem (lub coś podobnego). – chwarr

16

Ogólnie byłoby lepiej przekazać informacje do skryptu za pośrednictwem parametru, a nie zmiennej globalnej . Ale jeśli to, co trzeba zrobić, a chcesz automatyczne czyszczenie zmiennej następnie wprowadzić nowy zakres tak:

& { $foo = 'bar'; $env:foo = 'bar'; ./myscript } 

Kilka rzeczy, aby pamiętać o tym. Po pierwsze, gdy zakres (scriptblock) zostanie zakończony, $ foo już nie istnieje. Istniał tylko w kontekście bloku skryptów. Jednak zmienna środowiskowa $ env: foo nadal istnieje, ponieważ jest to prawdziwa globalna zmiana. Można usunąć tę zmienną tak:

Remove-Item Env:\foo 
+1

Pomyślnie: Czy nie mógłbyś odrodzić nowego procesu PowerShell, przekazując do niego blok skryptów za pomocą parametru -Command? W ten sposób nie będziesz musiał później oczyszczać środowiska, ponieważ będzie to zawarte w procesie potomnym. Chociaż mówię do MVP PowerShell, więc to prawdopodobnie nie działa :-) – Joey

+2

Keith, mamy pop-environmentblock i pop-environmentblock w Pscx dla dokładnie tego scenariusza ;-) – x0n

+2

Johannes, to by działało tak dobrze, ale jakoś wygląda na to, że oszukuje. :-) PSCX Push/Pop-EnvironmentBlock (ten * I * zmieniony tak, by działał w ten sposób) działał, ale nie ma funkcji automatycznego czyszczenia, którą posiada skryptblock. –

2

Aby osiągnąć równowartość składni Unix, nie tylko trzeba ustawić zmienną środowiskową, ale trzeba przywrócić go do dawnej wartości po wykonaniu komendy. Osiągnąłem to dla popularnych 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 różnie w zależności od wartości zmiennej środowiskowej app_master. Definiując cmd_special, mogę teraz wykonać cmd_special z wiersza poleceń (w tym inne parametry) z zestawem zmiennych środowiskowych app_master ... i zostanie on zresetowany (lub nawet anulowany) po wykonaniu polecenia.

Przypuszczalnie można to zrobić również 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 powłokę. Może przyszła wersja (lub funkcja strony trzeciej) ułatwi korzystanie z tego przypadku. Byłoby miło, gdyby Powershell miał polecenie cmdlet, które mogłoby to zrobić, np.:

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

Być może guru Powershell może zasugerować, w jaki sposób można napisać takie polecenie cmdlet.

0

mam motywację wystarczająco dużo o tym problemie, który poszedł do przodu i napisał scenariusz do niego: with-env.ps1

Zastosowanie:

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 zainstalować Gow można użyć env.exe który może być trochę bardziej wytrzymały niż szybki skrypt, który napisałem powyżej.

Zastosowanie:

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 
Powiązane problemy