Eksportowanie zmiennej z kropką (.)


38

Jak wyeksportować zmienną z kropką. Otrzymuję „niepoprawną nazwę zmiennej”, gdy próbuję:

 export my.home=/tmp/someDir
-ksh: my.home=/tmp/someDir: invalid variable name

Nawet ucieczka przed metaznakiem kropka (.) Nie pomogła

$ export my\.home=/tmp/someDir
export: my.home=/tmp/someDir: is not an identifier


1
niestety nie ma go na liście, kiedy wpisałem / szukałem podobnego pytania. Przepraszam. ..
user1587504

Odpowiedzi:


49

Przynajmniej dla bashstrony man definiuje składnię eksportu jako:

export [-fn] [name[=word]] ...

Definiuje także „nazwę” jako:

   name   A  word  consisting  only  of alphanumeric characters and under
          scores, and beginning with an alphabetic character or an  under
          score.  Also referred to as an identifier.

Dlatego tak naprawdę nie można zdefiniować takiej zmiennej, my.homeponieważ nie jest ona prawidłowym identyfikatorem.

Jestem pewien, że twój ksh ma bardzo podobną definicję identyfikatora, dlatego też nie dopuszcza tego rodzaju zmiennych. (Zajrzyj na jego stronę podręcznika).

Jestem również bardzo pewien, że istnieje jakiś ogólny standard (POSIX?) Określający, co jest dozwolone jako identyfikator (a zatem nazwa zmiennej).


Jeśli naprawdę potrzebujesz tego rodzaju zmiennej z jakiegoś powodu, możesz użyć czegoś takiego

env "my.home=/tmp/someDir" bash

i tak to zdefiniować. Ale z drugiej strony nie będzie można uzyskać do niego dostępu przy użyciu normalnej składni powłoki. W takim przypadku prawdopodobnie potrzebujesz innego języka, takiego jak perl:

perl -e 'print $ENV{"my.home"}'

Na przykład

env "my.home=/tmp/someDir" perl -le 'print $ENV{"my.home"}'

powinien wydrukować swoją ścieżkę.


Wynika to z integracji mrówek. I niestety nie pozwala na ustawianie / eksportowanie zmiennych z unixa. Akceptując twoją odpowiedź. ..
user1587504

1
mrówka jest zwykle konfigurowana przez pojedynczą zmienną środowiskową o nazwie ANT_OPTSlub ~ / .antrc. Nie potrzeba osobliwych nazw zmiennych środowiskowych dla samego mrówka.
michas

8

Podczas gdy zmienne środowiskowe mogą mieć dowolną nazwę (w tym pusty ciąg znaków) niezawierającą znaku równości lub bajtu zerowego, powłoki odwzorowują zmienne środowiskowe na zmienne powłoki, aw większości powłok nazwy zmiennych są ograniczone do znaków alfanumerycznych ASCII i _gdzie pierwszy znak może „ t być cyfra (z wyjątkiem parametrów pozycyjnych i innych specjalnych, takich jak te $*, $-, $@, ..., (które nie są przypisane do odpowiednich zmiennych środowiskowych)). Zauważ też, że niektóre zmienne są zarezerwowane / specjalne przez / dla powłoki.

Wyjątki od tego:

  • rcPowłoki i jej pochodne, jak esi akangawesprzeć dowolną nazwę, z wyjątkiem ciąg pusty, a te, które są all-numeryczny lub zawierać =znaków (i zawsze wyeksportować wszystkie swoje zmienne środowiska, a strzeżcie zmiennych specjalnych podoba *, status, pid...):

    ; '%$£"' = test
    ; echo $'%$£"'
    test
    ; '' = x
    zero-length variable name
    ;
    

    Jednak używa własnego kodowania dla zmiennych, których nazwa nie zawiera alnums lub tablic, gdy są przekazywane w środowisku wykonywanych poleceń:

    $ rc -c '+ = zzz; __ = zzz; a = (zzz xxx); env' | sed -n /zzz/l
    __2b=zzz$
    __5f_=zzz$
    a=zzz\001xxx$
    $ env +=x rc -c "echo $'+'"
    x
    $ env __2b=x rc -c "echo $'+'"
    x
    
  • AT & T ksh, yasha zsh(również bashale tylko dla znaków jednobajtowych) alnums wsparcia w bieżącej lokalizacji, a nie tylko te, które ASCII.

    $ Stéphane=1
    $ echo "$Stéphane"
    1
    

    W tych powłokach można zmienić ustawienia regionalne, aby większość znaków traktować jako alfa, ale nadal nie działałoby to w przypadku znaków ASCII, takich jak .. Możesz oszukiwać zshlub kshmyśleć, że £to litera, ale nie ta .lub jakikolwiek inny znak ASCII (w przypadku dopuszczenia znaków w nazwach zmiennych, nie [[:alpha:]]na przykład dla globu).

  • ksh93ma specjalne zmienne, których nazwa zawiera kropkę ${.sh.version}, ale nie są odwzorowane na zmienne środowiskowe i są wyjątkowe. Ma .to na celu upewnienie się, że nie powoduje konfliktu z innymi zmiennymi. Gdyby zdecydował się go wywołać $sh_version, mógłby mieć potencjalnie uszkodzone skrypty, które już używały tej zmiennej (zobacz na przykład, w jaki sposób występują zshproblemy z jej $pathlub $commandsspecjalnymi zmiennymi tablicowymi / mieszającymi (a la csh), które psują niektóre skrypty).

Należy pamiętać, że oprócz muszli nie wspierających takie zmienne, jak niektóre powłoki pdksh / mksh uwagi usunąć je z otoczenia, które otrzymują ( bashusuwa jedną z pustą nazwą ash, ksha bashusunąć te ciągi środowiskowe, które nie zawierają =znaków):

$ env %%%=test 1=%%% a.b=%%% mksh -c env | grep %%%
$ env %%%=test 1=%%% a.b=%%% bash -c env | grep %%%
%%%=test
a.b=%%%
1=%%%

$ perl -le '$ENV{""}="%%%"; exec "bash", "-c", "env"' | grep %%%
$ perl -le '$ENV{""}="%%%"; exec "zsh", "-c", "env"' | grep %%%
=%%%

$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
    execve("/bin/ash",a,e);}'|tcc -run - | grep %%%
$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
    execve("/bin/zsh",a,e);}'|tcc -run - | grep %%%
%%%

Podsumowując, najlepiej jest trzymać się nazw zmiennych obsługiwanych przez większość muszli, a nawet próbować używać dużych liter dla zmiennych środowiskowych (i małe litery lub mieszane przypadku nie wywiezionych zmiennych powłoki) unikanie tych, które są wyjątkowe w muszli (jak IFS, PS1, BASH_VERSION...)

Jeśli musisz ustawić taką zmienną w powłoce, która ich nie obsługuje, ale ich nie odrzuca, możesz albo sam wykonać ponownie, używając czegoś takiego:

#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"

(oczywiście, jeśli musisz to zrobić w środku skryptu, to nie pomoże, ale możesz rzucić okiem na to podejście do zapisywania i przywracania środowiska wykonywania powłoki po ponownym wykonaniu). Lub wypróbuj metodę debuggera:

gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"

(to zdaje się pracy z zsh, yash, cshi tcshna Linux amd64, ale nie z żadnym z innych skorup próbowałem ( mksh, ksh93, bash, dash)).


1
mksh(i pdksh) faktycznie konstruują procesy środowiskowe, które odradzają, otrzymywane całkowicie od zera, wykorzystując tylko parametry wyeksportowane w bieżącym środowisku wykonawczym powłoki, więc nie ma sposobu na przekazanie tych zmiennych przez te powłoki. (Zauważ, że zmienne, które przekazywane mogą ulec zmianie, np Planuję eksportu tablicy wsparcia dla mkshpewnego dnia.)
mirabilos

0

Jak wskazują inne posty, najpopularniejsze powłoki nie pozwalają na ustawianie zmiennych środowiskowych z kropkami w nazwie. Znalazłem jednak sytuacje, w szczególności dotyczące Dockera i wywoływanych programów, w których oprogramowanie wymagało kluczowych wartości z kropkami.

Jednak w każdej z tych sytuacji te pary klucz-wartość można przekazać do programu innymi sposobami niż tylko zmiennymi środowiskowymi. Na przykład w Ant można użyć „-propertyfile (nazwa_pliku)”, aby przekazać do zbioru właściwości klucz sformatowany w pliku właściwości. Confd pozwala na „-backend file -file (plik yaml)”.

Przekazałem zmienne środowiskowe w postaci „C__any_value = 'my.property.key = wartość'”. Następnie przełączyłem wywołanie programu, aby najpierw wygenerować plik:

set | awk -- 'BEGIN { FS="'\''" } /^C__/ {print $2}' > my-key-values.txt

setPoleceń, w Borne Shell, pokaże na wyjściu każdej nieruchomości na osobnej linii w formie

C__any_value='my.property.key=the value'

awkPolecenie przetwarzać tylko zmienne środowiska zaczynające się C__, a następnie wyodrębnić wartości zawartych w z apostrofami.

Ta metoda wymaga ustawienia wartości zmiennej środowiskowej w dokładnej formie wymaganej przez program przetwarzający. Dodatkowo, jeśli twoja wartość właściwości lub klucz będzie zawierał pojedyncze cudzysłowy, musisz zmienić znak separatora pola awk na coś, o czym wiesz, że się nie pojawi, i otoczyć wartość tym znakiem. Na przykład, aby użyć %jako separatora:

$ C__1="%my.key=the'value%"
$ set | awk -- 'BEGIN { FS="%" } /^C__/ {print $2}'
my.key=the'"'"'value

(dokładne wyniki zależą od powłoki). Będziesz musiał podjąć dodatkowe kroki, aby zdekodować ucieczkę cytatu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.