Exportieren einer Variablen mit Punkt (.)

38

So exportieren Sie eine Variable, die einen Punkt enthält. Ich erhalte einen ungültigen Variablennamen, als ich versuchte:

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

Auch das Entweichen von Metazeichen (.) Hilft nicht weiter

$ export my\.home=/tmp/someDir
export: my.home=/tmp/someDir: is not an identifier
user1587504
quelle
1
Leider ist es nicht aufgeführt, als ich eine ähnliche Frage eingegeben / gesucht habe. Es tut uns leid. ..
user1587504

Antworten:

49

Zumindest für bashdie Manpage definiert man die Exportsyntax als:

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

Es definiert auch einen "Namen" als:

   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.

Daher können Sie eine Variable wirklich nicht definieren, my.homeda es sich nicht um einen gültigen Bezeichner handelt.

Ich bin mir sehr sicher, dass Ihre ksh eine sehr ähnliche Definition eines Bezeichners hat und daher auch diese Art von Variablen nicht zulässt. (Schauen Sie sich die Manpage an.)

Ich bin mir auch sehr sicher, dass es eine Art allgemeinen Standard (POSIX?) Gibt, der angibt, was als Bezeichner (und daher als Variablenname) zulässig ist.


Wenn Sie diese Art von Variable aus irgendeinem Grund wirklich brauchen, können Sie so etwas verwenden

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

es trotzdem zu definieren. Andererseits können Sie mit der normalen Shell-Syntax nicht darauf zugreifen. In diesem Fall benötigen Sie wahrscheinlich eine andere Sprache wie Perl:

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

Beispielsweise

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

sollte Ihren Pfad drucken.

michas
quelle
Es liegt an der Integration der Ameise. Und leider erlaubt es nicht, Variablen von Unix zu setzen / exportieren. Akzeptiere deine Antwort. ..
user1587504
1
ant wird normalerweise von einer einzelnen Umgebungsvariablen namens ANT_OPTSoder von ~ / .antrc konfiguriert. Keine Notwendigkeit für seltsame Umgebungsvariablennamen für ant selbst.
Michas
8

Während Umgebungsvariablen einer beliebigen Namen (einschließlich dem leeren String) hat nicht ein Gleichheitszeichen oder einen Null - Byte enthält, Karte shells Umgebungsvariablen Variablen und in den meisten Muscheln, Variablennamen in ASCII - alphanumerischen Zeichen und begrenzt sind , Shell , _wo das erste Zeichen kann‘ t sein eine Ziffer ( mit Ausnahme der Positionsparameter und andere besondere diejenigen wie $*, $-, $@, ..., (die nicht zu den entsprechenden Umgebungsvariablen abgebildet werden)). Beachten Sie auch, dass einige Variablen von / für die Shell reserviert / speziell sind .

Ausnahmen davon:

  • Die rcSchale und seine Derivate wie esund akangaunterstützen einen beliebigen Namen außer den leeren String, und diejenigen , die alle numerischen sind oder enthalten =Zeichen (und immer alle ihre Variablen in die Umgebung zu exportieren, und passen Sie von speziellen Variablen wie *, status, pid...):

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

    Es verwendet jedoch eine eigene Codierung für Variablen, deren Name keine Alarme enthält, oder für Arrays, die in der Umgebung von Befehlen übergeben werden, die ausgeführt werden:

    $ 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, yashund zsh(auch , bashaber nur für Single-Byte - Zeichen) Unterstützung alnums in den aktuellen Locale, nicht nur ASCII diejenigen.

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

    In diesen Shells können Sie das Gebietsschema so ändern, dass die meisten Zeichen als Alpha betrachtet werden. Bei ASCII-Zeichen wie z .. Sie können täuschen zshoder kshdenken, dass £es sich um einen Buchstaben handelt, aber nicht um dieses .oder ein anderes ASCII-Zeichen (wenn es darum geht, Zeichen in Variablennamen zuzulassen, beispielsweise nicht für den [[:alpha:]]Glob).

  • ksh93hat spezielle Variablen, deren Name einen Punkt wie enthält ${.sh.version}, aber diese sind nicht Umgebungsvariablen zugeordnet und sind speziell. Das .ist um sicherzustellen , dass es nicht mit anderen Variablen in Konflikt geraten. Wenn es sich dafür entschieden hätte, es aufzurufen $sh_version, könnte es möglicherweise Skripte beschädigt haben, die diese Variable bereits verwendet haben (siehe zum Beispiel, wie zshProbleme mit ihren $pathoder $commandsspeziellen Array- / Hash-Variablen (a la csh) auftreten, die einige Skripte beschädigen).

Beachten Sie, dass zusätzlich zu den Schalen nicht diese Variablen, einige Shells wie pdksh Stütz- / mksh tun entfernen sie aus der Umgebung , die sie erhalten ( bashentfernt die man mit einem leeren Namen ash, kshund bashdiese Umgebung Strings entfernen, die keine enthalten =Zeichen):

$ 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 %%%
%%%

Um es zusammenzufassen, ist am besten mit Variablennamen von den meisten Schalen unterstützt zu halten und versuchen , auch Großbuchstaben für Umgebungsvariablen zu verwenden (und Kleinschreibung oder gemischter Fall für nicht-exportierte Shell - Variablen) vermieden werden diejenigen , die in Schalen speziell sind (wie IFS, PS1, BASH_VERSION...).

Wenn Sie eine solche Variable in einer Shell festlegen müssen, die sie nicht unterstützt, aber nicht verwirft, können Sie sie entweder selbst erneut ausführen.

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

(Wenn Sie dies in der Mitte des Skripts tun müssen, hilft das natürlich nicht weiter. Sie können sich jedoch diesen Ansatz ansehen , um die Shell-Ausführungsumgebung über eine erneute Ausführung zu speichern und wiederherzustellen.) Oder probieren Sie den Debugger-Ansatz:

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

(dass man Arbeit scheint mit zsh, yash, cshund tcshauf Linux amd64, aber nicht mit einer der anderen Shells ich versuchte ( mksh, ksh93, bash, dash)).

Stéphane Chazelas
quelle
1
mksh(und pdksh) konstruieren Sie tatsächlich die Umgebungsprozesse, die sie erzeugen, komplett neu, indem Sie nur die Parameter verwenden, die in der aktuellen Shell-Ausführungsumgebung exportiert wurden. Es gibt also keine Möglichkeit, diese Variablen durch diese Shells zu leiten. (Beachten Sie, dass die Variablen , die sind vergangen sind Änderungen vorbehalten, zB ich plane zu Unterstützung Array Exporte für mksheinige Tage.)
mirabilos
0

Wie in den anderen Beiträgen bereits erwähnt, können in den gängigsten Shells keine Umgebungsvariablen mit Punkten im Namen festgelegt werden. Ich habe jedoch Situationen festgestellt, die insbesondere Docker und aufgerufene Programme betrafen, in denen die Software Schlüsselwerte mit Punkten erforderte.

In jeder dieser Situationen können diese Schlüssel-Wert-Paare jedoch nicht nur über Umgebungsvariablen an das Programm übergeben werden. In Ant können Sie beispielsweise "-propertyfile (filename)" verwenden, um eine mit einer Eigenschaftendatei formatierte Auflistung von Schlüsselwerten zu übergeben. Confd erlaubt "-backend file -file (yaml file)".

Ich habe die Umgebungsvariablen in der Form "C__any_value = 'my.property.key = the value'" übergeben. Ich habe dann den Programmaufruf gewechselt, um zuerst die Datei zu generieren:

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

Der setBefehl in Borne Shell gibt jede Eigenschaft in einer separaten Zeile im Formular aus

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

Der awkBefehl verarbeitet nur die Umgebungsvariablen, die mit beginnen C__, und extrahiert dann die in den einfachen Anführungszeichen enthaltenen Werte.

Bei dieser Methode muss der Wert der Umgebungsvariablen in der für das Verarbeitungsprogramm erforderlichen Form festgelegt werden. Wenn Ihr Eigenschaftswert oder Schlüssel einfache Anführungszeichen enthält, müssen Sie das awk-Feldtrennzeichen in etwas ändern, von dem Sie wissen, dass es nicht angezeigt wird, und den Wert mit diesem Zeichen umgeben. Zum Beispiel %als Trennzeichen verwenden:

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

(Die genaue Ausgabe hängt von Ihrer Shell ab.) Sie müssen zusätzliche Schritte ausführen, um das entstehende Anführungszeichen zu decodieren.

Groboclown
quelle