Mogę ENV_VAR=value commandbiegać commandz określoną wartością dla ENV_VAR. Co to jest równoważne rozbroić ENV_VARza command?
cmddo tego.
Mogę ENV_VAR=value commandbiegać commandz określoną wartością dla ENV_VAR. Co to jest równoważne rozbroić ENV_VARza command?
cmddo tego.
Odpowiedzi:
Poza -iopcją, która usuwa całe środowisko, POSIX envnie zapewnia żadnego sposobu na rozbrojenie zmiennej.
Jednak za pomocą kilku envimplementacji (w tym busyboxco najmniej GNU, 'i FreeBSD) możesz:
env -u ENV_VAR command
Który działałby przy usuwaniu każdego wystąpienia ENV_VARzmiennej ze środowiska (zauważ jednak, że nie działa on dla zmiennej środowiskowej o pustej nazwie ( env -u ''albo daje błąd, albo jest nieskuteczny w zależności od implementacji, mimo że wszystkie akceptują env '=value', prawdopodobnie ograniczenie) ponoszone przez funkcję unsetenv()C, która POSIX wymaga zwrócenia błędu pustego łańcucha, podczas gdy nie ma takiego ograniczenia putenv())).
Przenośnie (w powłokach POSIX) możesz:
(unset -v ENV_VAR; exec command)
(zwróć uwagę, że w przypadku niektórych powłok użycie polecenia execcan change, które commandjest uruchomione: uruchamia ten w systemie plików zamiast funkcji lub na przykład wbudowanego (i aliasoczywiście envpomija rozszerzenie), jak wyżej. W takich przypadkach należy go pominąć) .
Ale to nie zadziała w przypadku zmiennych środowiskowych, których nazwy nie da się zmapować na zmienną powłoki (zwróć uwagę, że niektóre takie powłoki i tak usuwają mkshte zmienne ze środowiska podczas uruchamiania), lub zmienne oznaczone jako tylko do odczytu.
-vjest dla powłoki Bourne'a i bez bashktórej mogłaby rozbroić funkcję, gdyby nie było zmiennej o tej nazwie. Większość innych powłok nie rozbroiłaby funkcji, chyba że podasz opcję. (mało prawdopodobne, aby zmieniło się w praktyce).unset-vENV_VAR -f
(Uważaj również na błąd / błędne działanie bash/ mksh/ yashktórego unsetw pewnych okolicznościach może nie rozbroić zmiennej, ale ujawnić zmienną w zakresie zewnętrznym )
Jeśli perljest dostępny, możesz:
perl -e 'delete $ENV{shift@ARGV}; exec @ARGV or die$!' ENV_VAR command
Który będzie działał nawet dla zmiennej środowiskowej o pustej nazwie.
Teraz wszystkie te nie będą działać, jeśli chcesz zmienić zmienną środowiskową dla wbudowanej funkcji lub funkcji i nie chcesz, aby działały w podpowłoce, np . bash:
env -u LANG printf -v var %.3f 1.2 # would run /usr/bin/printf instead
(unset -v LANG; printf -v var %.3f 1.2) # changes to $var lost afterwards
(tutaj rozbrajanie LANG jako błędne podejście do upewnienia się, że .jest używane i rozumiane jako separator dziesiętny. Lepiej byłoby użyć LC_ALL=C printf...do tego)
W przypadku niektórych powłok można zamiast tego utworzyć zasięg lokalny dla zmiennej za pomocą funkcji:
without() {
local "$1" # $1 variable declared as initially unset in bash¹
shift
"$@"
}
without LANG printf -v var %.3f 1.2
Za pomocą zshmożesz także użyć anonimowej funkcji:
(){local ENV_VAR; command}
Takie podejście nie będzie działać w niektórych powłokach (takich jak te oparte na powłoce Almquist), localktóre nie deklarują zmiennej jako początkowo nieuzbrojonej (ale dziedziczą wartość i atrybuty). W tych przypadkach możesz to zrobić local ENV_VAR; unset ENV_VAR, ale nie rób tego w mkshlub yash( typesetzamiast localtego), ponieważ to nie zadziała, unsetbyłoby tylko anulowanie local.
¹ Strzeż się również, że w bashtym przypadku lokalny ENV_VAR(nawet jeśli nie jest ustawiony) zachowałby atrybut eksportu . Gdyby więc commandbyła funkcja, która przypisuje wartość ENV_VAR, zmienna byłaby dostępna w środowisku poleceń wywoływanych później. unset ENV_VARwyczyści ten atrybut. Lub możesz użyć tego, local +x ENV_VARco zapewniłoby również czyste konto (chyba że zmienna została zadeklarowana jako tylko do odczytu, ale wtedy nic nie możesz na to poradzić bash).
env '=foo' python -c 'import os; print os.environ[""]'. Nie oczekuję, że wiele osób chciałoby ustawić taką zmienną.
O ile mi wiadomo, nie ma bezpośredniego odpowiednika; możesz użyć podpowłoki:
(unset ENV_VAR; exec command)
(unset ENV_VAR; exec somecommand)jeśli chcesz być równoważny z oryginałem pod względem wydajności (poprzez konsumpcję podpowłoki). W tej chwili dodaje to dodatkowy widelec.
commandjest to ostatnie polecenie w wywołaniu podpowłoki.
env -u.
Możesz użyć ENV_VAR= command
W rzeczywistości nie powoduje to rozbrojenia zmiennej, ale może być przydatne w wielu przypadkach (skrypty powłoki zwykle służą test -ndo sprawdzenia, czy zmienna jest ustawiona):
$ export ENV_VAR=foo
$ mycommand
ENV_VAR: foo
$ ENV_VAR=bar mycommand
ENV_VAR: bar
$ ENV_VAR= mycommand
ENV_VAR:
commandjest niefortunnym wyborem symboli zastępczych, ponieważ tak naprawdę istnieje wbudowane polecenie o tej nazwie.mycommandlubsomecommandcoś takiego może być lepszym nawykiem do wejścia.