Jak ustawić zmienną środowiskową tylko na czas trwania skryptu?

127

Czy w systemie Linux (Ubuntu 11.04) w bash można tymczasowo ustawić zmienną środowiskową, która będzie się różnić od zwykłej zmiennej tylko na czas trwania skryptu? Na przykład, w skrypcie powłoki, utworzenie przenośnej aplikacji, która zapisuje w HOME, poprzez tymczasowe ustawienie HOME na folder w obecnym katalogu roboczym, a następnie uruchomienie aplikacji.

suchipi
źródło
5
Byłoby trudniej, gdybyś chciał, aby ustawienie trwało dłużej niż czas trwania scenariusza
Nemo

Odpowiedzi:

119
VAR1=value1 VAR2=value2 myScript args ...
Rockallite
źródło
2
Sam robiłem to wiele razy, aby biegać vblank_mode=0 glxgears. Działa, ale mówi też vblank_mode=0: command not foundpo uruchomieniu, podczas gdy poprzedzanie envtego nie powoduje. [testowanie ...] Najwyraźniej zsh tego nie lubi (ale nadal używa go poprawnie), ale bash jest w porządku. Myślę, że envod teraz będę stosować tę metodę.
Chinoto Vokro
2
ze skryptami to działa, ale co powiesz na VAR1="hello" echo $VAR1to, że nic nie zwróci?
Zibri
2
@Zibri chodzi o to, kiedy trwa ekspansja. Prawdopodobnie możesz zrobić coś takiego:VAR1="hello" bash -c 'echo $VAR1'
cybergrind
Głosowano za pokazaniem, że jest to możliwe nawet dla wielu zmiennych środowiskowych.
Binarus
70
env VAR=value myScript args ...
glenn jackman
źródło
18
LubVAR=value myScript args ...
Rockallite
9
1. Dlaczego PATH=$PATH:XYZ echo $PATH | grep XYZjednak nie ma żadnego wyjścia? 2. Jaka jest różnica między używaniem a nieużywaniem env?
qubodup
18
ponieważ powłoka rozszerza zmienną PATH przed wykonaniem polecenia echo. Musisz opóźnić tę ekspansję. Jeden sposób: PATH=$PATH:XYZ sh -c 'echo $PATH' | grep XYZ- pojedyncze cudzysłowy są tutaj kluczowe
glenn jackman
14
Jaka jest różnica między używaniem enva niekorzystaniem z niego?
Mohammed Noureldin
Wydaje się, że to nie działa w onelinerze takim jakIFS=$'\n' for l in lines; do ... done
drevicko
31

Po prostu włóż

export HOME=/blah/whatever

w miejscu skryptu, w którym ma nastąpić zmiana. Ponieważ każdy proces ma swój własny zestaw zmiennych środowiskowych, definicja ta automatycznie przestanie mieć jakiekolwiek znaczenie po zakończeniu działania skryptu (a wraz z nim instancji basha ze zmienionym środowiskiem).

hmakholm zostawił Monikę
źródło
11
To jest mylące. exportprzekaże zmienną do podpowłok, ale nie kontroluje powłoki nadrzędnej. Jeśli piszesz skrypt, który zaczyna się od „#! / Bin / sh” lub podobnego, KAŻDA ustawiona zmienna zniknie po zakończeniu działania skryptu.
brightlancer
1
@brightlancer, to prawda, ale nie zaprzecza temu, co napisałem. (Z wyjątkiem możliwości, że skrypt może rozpocząć proces w tle, ale myślę, że jest to poza poziomem zaawansowania programu operacyjnego i tylko myliłoby).
hmakholm opuścił Monikę
5
Eksport jest zbędny. Twoja odpowiedź działa tylko wtedy, gdy jego skrypt wywołuje interpreter (#! / Bin / sh lub tym podobne). Jeśli jego „scenariusz” tego nie zrobi, to to, co mu właśnie powiedziałeś, będzie obowiązywało po jego zakończeniu. Dlatego powiedziałem, że twoja odpowiedź jest myląca - może być poprawna, może nie, ale na pewno zawiera część, która jest niepotrzebna i myląca, ponieważ może spowodować, że ktoś pomyśli, że „eksport” jest niezbędnym elementem, którego szukał.
brightlancer
7
@brightlancer: Eksport jest konieczny, jeśli skrypt OP wywołuje podskrypty, które same zależą od $ HOME, a nie odważyłem się założyć, że tak nie jest. Co więcej, bash utworzy podpowłokę, aby uruchomić skrypt, nawet jeśli skrypt nie ma linii shebang, ale jest tylko plikiem tekstowym z ustawionym bitem wykonania. Spróbuj - przypisania zmiennych w skrypcie nie są widoczne w powłoce, z której go wywołałeś. Tylko jeśli jawnie podasz sourceskrypt, zostanie on wykonany przez tę samą powłokę, w której wpiszesz polecenie.
hmakholm opuścił Monikę
4
@brightlancer: Eksport jest konieczny, jeśli chce $HOMEon być dziedziczony przez jakiekolwiek polecenia wykonywane ze skryptu. A jeśli tego nie zrobi, a ustawienie $HOMEdziała tylko na korzyść samego skryptu, prawdopodobnie lepiej będzie zmodyfikować skrypt, aby odnosił się do czegoś innego niż $HOME.
Keith Thompson,