Zwykle możliwe jest ustawienie zmiennej środowiskowej dla polecenia poprzez prefiks:
hello=hi bash -c 'echo $hello'
Wiem również, że możemy użyć zmiennej, aby zastąpić dowolną część wywołania polecenia, taką jak:
$ cmd=bash
$ $cmd -c "echo hi" # equivalent to bash -c "echo hi"
Byłem bardzo zaskoczony, gdy dowiedziałem się, że nie można użyć zmiennej do prefiksu polecenia w celu ustawienia zmiennej środowiskowej. Przypadek testowy:
$ prefix=hello=hi
$ echo $prefix # prints hello=hi
$ $prefix bash -c 'echo $hello'
hello=hi: command not found
Dlaczego nie mogę ustawić zmiennej środowiskowej za pomocą zmiennej? Czy część przedrostka jest częścią specjalną? Udało mi się go uruchomić, używając eval z przodu, ale nadal nie rozumiem, dlaczego. Używam bash 4.4.
bash
environment-variables
variable
wbkang
źródło
źródło
env
zamiast tegoeval
, który IIRC jest bezpieczniejszy, ale wolniejszy.Odpowiedzi:
Podejrzewam, że jest to część sekwencji, która Cię łapie:
To pochodzi z podręcznika użytkownika Bash w rozdziale Prosta rozbudowa poleceń.
W tym
cmd=bash
przykładzie nie ustawiono żadnych zmiennych środowiskowych, a bash przetwarza wiersz poleceń w górę poprzez rozwijanie parametrów, pozostawiającbash -c "echo hi"
.W tym
prefix=hello=hi
przykładzie ponownie nie ma przypisań zmiennych w pierwszym przejściu, więc przetwarzanie kontynuuje ekspansję parametrów, w wyniku czego powstaje pierwsze słowohello=hi
.Po przetworzeniu przypisań zmiennych nie są one ponownie przetwarzane podczas wykonywania polecenia.
Zobacz przetwarzanie i jego wyniki w
set -x
:Aby uzyskać bezpieczniejszą odmianę „zmiennych ekspansji” -as- „zmiennych środowiskowych”
eval
, rozważ sugestię wjandrea dotyczącąenv
:Nie jest to ściśle przypisanie zmiennych wiersza poleceń, ponieważ używamy
env
głównej funkcji narzędzia do przypisywania zmiennych środowiskowych do polecenia, ale osiąga ten sam cel.$prefix
Zmienna jest rozszerzona podczas przetwarzania poleceń linii podanie nazwy = wartośćenv
, która przekazuje je wraz zbash
.źródło
$foo=bar bash -c ...
nie będzie działać, ponieważ$foo=bar
nie jest przypisaniem zmiennej (niezależnie od wartości$foo
), ponieważ$foo=bar
nie pasuje doname=value
wzorca dla przypisania zmiennej.Ponieważ
$prefix
to nie jest zadanie. @Jeff ma dłuższe wyjaśnienie .Zamiast tego możesz zrobić coś podobnego z funkcją:
... i możesz je układać, jeśli chcesz:
źródło