Mogę ENV_VAR=value command
biegać command
z określoną wartością dla ENV_VAR
. Co to jest równoważne rozbroić ENV_VAR
za command
?
cmd
do tego.
Mogę ENV_VAR=value command
biegać command
z określoną wartością dla ENV_VAR
. Co to jest równoważne rozbroić ENV_VAR
za command
?
cmd
do tego.
Odpowiedzi:
Poza -i
opcją, która usuwa całe środowisko, POSIX env
nie zapewnia żadnego sposobu na rozbrojenie zmiennej.
Jednak za pomocą kilku env
implementacji (w tym busybox
co najmniej GNU, 'i FreeBSD) możesz:
env -u ENV_VAR command
Który działałby przy usuwaniu każdego wystąpienia ENV_VAR
zmiennej 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 exec
can change, które command
jest uruchomione: uruchamia ten w systemie plików zamiast funkcji lub na przykład wbudowanego (i alias
oczywiście env
pomija 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ą mksh
te zmienne ze środowiska podczas uruchamiania), lub zmienne oznaczone jako tylko do odczytu.
-v
jest dla powłoki Bourne'a i bez bash
któ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
-v
ENV_VAR
-f
(Uważaj również na błąd / błędne działanie bash
/ mksh
/ yash
którego unset
w pewnych okolicznościach może nie rozbroić zmiennej, ale ujawnić zmienną w zakresie zewnętrznym )
Jeśli perl
jest 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ą zsh
moż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), local
któ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 mksh
lub yash
( typeset
zamiast local
tego), ponieważ to nie zadziała, unset
byłoby tylko anulowanie local
.
¹ Strzeż się również, że w bash
tym przypadku lokalny ENV_VAR
(nawet jeśli nie jest ustawiony) zachowałby atrybut eksportu . Gdyby więc command
była funkcja, która przypisuje wartość ENV_VAR
, zmienna byłaby dostępna w środowisku poleceń wywoływanych później. unset ENV_VAR
wyczyści ten atrybut. Lub możesz użyć tego, local +x ENV_VAR
co 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.
command
jest 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 -n
do 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:
command
jest niefortunnym wyborem symboli zastępczych, ponieważ tak naprawdę istnieje wbudowane polecenie o tej nazwie.mycommand
lubsomecommand
coś takiego może być lepszym nawykiem do wejścia.