Zulässige Zeichen in Linux-Umgebungsvariablennamen

143

Welche Zeichen sind in Linux-Umgebungsvariablennamen zulässig? Meine flüchtige Suche in Manpages und im Web ergab nur Informationen darüber, wie mit Variablen gearbeitet wird, nicht jedoch, welche Namen zulässig sind.

Ich habe ein Java-Programm, das eine definierte Umgebungsvariable benötigt, die einen Punkt enthält, wie z com.example.fancyproperty. Unter Windows kann ich diese Variable einstellen, aber ich hatte kein Glück, sie unter Linux einzustellen (versucht in SuSE und Ubuntu). Ist dieser Variablenname überhaupt erlaubt?

Christian Semrau
quelle
3
Glücklicherweise stellte ich fest, dass das Programm mit einer Java-Systemeigenschaft (die mit einer -DBefehlszeilenoption deklariert wurde) genauso zufrieden ist , sodass es jetzt funktioniert. Offensichtlich sieht das Programm in beiden Variablensätzen aus, ohne es mir zu sagen. Trotzdem bin ich gespannt, welche Umgebungsvariablennamen zulässig sind.
Christian Semrau
@AleksandrDubinsky Ich habe es gelöscht. Dies ist ähnlich, aber über Alias ​​Definition nicht genau Umgebungsvariablen stackoverflow.com/questions/24690640/…
Lime
1
Wenn Sie mit Frühling , dann wird der Standard SystemEnvironmentPropertySource auch nachschlagen com_example_fancypropertyund COM_EXAMPLE_FANCYPROPERTY.
Aleksandr Dubinsky

Antworten:

203

Aus der offenen Gruppe :

Diese Zeichenfolgen haben die Form name = value; Namen dürfen nicht das Zeichen '=' enthalten. Damit Werte systemübergreifend gemäß IEEE Std 1003.1-2001 portierbar sind, muss der Wert aus Zeichen aus dem portablen Zeichensatz bestehen ( außer NUL und wie unten angegeben ).

Namen können also beliebige Zeichen außer = und NUL enthalten, aber:

Umgebungsvariablennamen, die von den Dienstprogrammen im Shell- und Dienstprogramm-Volume von IEEE Std 1003.1-2001 verwendet werden, bestehen ausschließlich aus Großbuchstaben, Ziffern und dem '_' (Unterstrich) der im Portable Character Set definierten Zeichen und beginnen nicht mit einer Ziffer . Andere Zeichen können von einer Implementierung zugelassen werden. Anträge müssen das Vorhandensein solcher Namen tolerieren.

Während die Namen möglicherweise gültig sind, unterstützt Ihre Shell möglicherweise nur Buchstaben, Zahlen und Unterstriche.

Robert Gamble
quelle
8
Nur überprüfen: Das zweite Anführungszeichen ist nicht normativ: Es wird lediglich festgestellt, dass die Variablen, die POSIX als speziell für seine Dienstprogramme definiert, sind [a-zA-Z_][a-zA-Z0-9_]*(implizit bedeutet dies, dass dieses Formular vernünftiger ist), aber die tatsächliche Spezifikation (Anführungszeichen 1) erfordert, dass die gesamte Implementierung alles andere als unterstützt =und NUL?
Ciro Santilli 21 冠状 病 六四 事件 21
3
Außerdem enthält der "portable Zeichensatz" pubs.opengroup.org/onlinepubs/000095399/basedefs/… Dinge wie Leerzeichen und nicht druckbare Dateien. Können wir diese Dinge also verwenden oder nicht?
Ciro Santilli 法轮功 冠状 病 六四 事件 21
3
Genau das beobachte ich. Shell mag keine Sonderzeichen als Teil eines Variablennamens. Wenn jedoch ein Programm oder Skript (z. B. Java oder Perl) eine Variable mit Sonderzeichen im Namen initialisiert und eine andere ausführbare Datei (einen untergeordneten Prozess) aufruft, kann die letztere ausführbare Datei problemlos auf diese Variable zugreifen.
14.
1
@checksum, UPPERCASE wird explizit für Variablennamen angegeben, die für POSIX-angegebene Tools, einschließlich der Shell, von Bedeutung sind. Namen mit mindestens einem Kleinbuchstaben sind ausdrücklich für die Verwendung durch Anwendungen reserviert. Daher empfiehlt es sich, mindestens ein Kleinbuchstaben in die Variablennamen Ihrer Anwendungen aufzunehmen, um sicherzustellen, dass Sie eine Variable mit der Bedeutung to nicht unbeabsichtigt überschreiben (da durch das Festlegen einer Shell-Variablen jede gleichnamige Umgebungsvariable überschrieben wird) das System. Siehe pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Charles Duffy
2
@CiroSantilli 事件 事件 2016 六四 事件 法轮功, Sie können sie in Umgebungsvariablen verwenden; Sie können sie nicht in Shell-Variablen verwenden, und es ist nicht garantiert, dass auf diese Umgebungsvariablen über die Shell zugegriffen werden kann.
Charles Duffy
37

Der Abschnitt POSIX-Standards für Shells von IEEE Std 1003.1-2008 / IEEE POSIX P1003.2 / ISO 9945.2 Der Shell- und Tools-Standard definiert die lexikalische Konvention für Variablennamen nicht. Ein flüchtiger Blick auf die Quelle zeigt jedoch, dass etwas Ähnliches verwendet wird

[a-zA-Z_]+[a-zA-Z0-9_]*

(Bearbeiten: Fehlender Unterstrich in der 2. Zeichenklasse hinzugefügt.)

Ein kurzer Hinweis: Da einige Shells das + in Regex nicht unterstützen, kann ein möglicherweise portablerer Regex sein:

[a-zA-Z_]{1,}[a-zA-Z0-9_]{0,}

Aiden Bell
quelle
4
Danke, Aiden. Ich denke, in der zweiten Reihe eckiger Klammern fehlt ein Unterstrich: Es sollte wahrscheinlich lauten: [a-zA-Z_][a-zA-Z0-9_]* Für diejenigen wie mich, die den Verweis auf bash-4.1 etwas vage finden (616'000 Codezeilen), sind hier einige Hinweise Suchen Sie die relevanten Codezeilen: subst.c: param_expand(), in the default case-> general.h:/ * Definieren Sie genau, woraus eine legale Shell-ID besteht. * / #define legal_variable_starter (c) (ISALPHA (c) || ​​(c == ' ')) #define legal_variable_char (c) (ISALNUM (c) || ​​c == ' ')
Chris
3
Das Plus brauchen Sie in der ersten Zeichenklasse nicht.
Scravy
2
@ scravy wahr, obwohl ich den regulären Ausdruck von der Quelle genommen habe, damit ich das + in behalten kann.
Aiden Bell
4
POSIX definiert: 3.231 Name a word consisting solely of underscores, digits, and alphabetics from the portable character set. The first character of a name is not a digit .
Nicht im Shell-Abschnitt, aber es gibt absolut POSIX-Standards, die Konventionen für die Benennung von Umgebungsvariablen enthalten (und tatsächlich Namen diskutieren, die für die Shell-Verwendung reserviert sind). Siehe pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Charles Duffy
12

Meine schnellen Tests haben gezeigt, dass sie grundsätzlich den gleichen Regeln folgen wie C-Variablennamen, nämlich

  1. az, AZ _und 0-9
  2. Darf NICHT mit einer Zahl beginnen

Das schließt also .in ihnen aus. Jeder unzulässige Variablenname wird gutgeschrieben unknown command.

Dies wurde in ZSH getestet, das größtenteils BASH-kompatibel ist.

LukeN
quelle
6

Kommt darauf an, was du mit "erlaubt" meinst.

Windows für das Nonce ignorieren:

Die Umgebung ist ein Array von Zeichenfolgen, die an die Hauptfunktion eines Programms übergeben werden. Wenn Sie execve (2) lesen, werden für diese Zeichenfolgen keine anderen Anforderungen oder Einschränkungen als die Nullterminierung angezeigt.

Konventionell besteht jede Zeichenfolge aus NAME = Wert. Es gibt keine Anführungszeichenkonvention, daher kann der Name in dieser Konvention kein '=' enthalten.

Normale Menschen setzen diese Fäden, indem sie sie mit ihrer Hülle besprechen. Jede Shell hat ihre eigenen Vorstellungen von gültigen variablen NAMEs. Sie müssen also die Manpage für die aktuelle Shell lesen, um zu sehen, was sie denkt.

Im Allgemeinen sind Dinge wie com.baseball.spit = fleagh Java-Systemeigenschaften. Unabhängig davon, ob ein Java-Programm bereit ist, auf die Umgebung zurückzugreifen, ist es besser, sie mit -D anzugeben.

bmargulies
quelle
Ich hätte früher zu dem Schluss kommen sollen, dass die Variable wie eine Java-Systemeigenschaft formatiert ist, anstatt zu versuchen, sie als Umgebungsvariable festzulegen.
Christian Semrau
5

Es kommt auf die Schale an. Ich vermute, Sie verwenden standardmäßig Bash. In diesem Fall sind Buchstaben, Zahlen und Unterstriche zulässig, aber Sie können den Variablennamen nicht mit einer Zahl beginnen. Ab Bash v.3 sind Punkte innerhalb von Variablennamen nicht mehr zulässig .

ire_and_curses
quelle
4

Ja, Sie können es tun.

Verwenden Sie execund envBefehl, um diese Szene zu implementieren.

Testvorrichtung in Docker

docker run -it --rm alpine:3.10

Befehl im Container ausführen:

exec env spring.application_name=happy-variable-name ${SHELL:-/bin/sh}

Umgebungsvariablen überprüfen:

HOSTNAME=bd0bccfdc53b
SHLVL=2
HOME=/root
spring.application_name=happy-variable-name
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/

Verwenden Sie ps auxdiese Option, um zu überprüfen, ob die PID nicht geändert wurde

PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
   12 root      0:00 ps aux

Verwenden Sie pythondiese Option, um die Umgebungsvariable zu überprüfen

apk add python
python -c 'import os; print(os.environ["spring.application_name"])'

AUSGABE ist happy-variable-name.

Was ist los?

  1. Shell-Aufruf eingebaut exec
  2. Shell-Exec-Aufruf syscall.exec create process 'env', um die aktuelle Shell zu ersetzen
  3. env-Prozessaufruf syscall.execvp create process '/ bin / sh', um den env-Prozess zu ersetzen

Ein anderer Weg

  • Docker-Bild

Wenn Sie Docker verwenden, können Sie in Dockerfile eine Variable festlegen

FROM busybox
ENV xx.f%^&*()$#ff=1234
  • Kubernetes configmap

Wenn Sie Kubernetes verwenden, können Sie die Variable über ConfigMap festlegen

test.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: foo-config
data:
  "xx.ff-bar": "1234"

---
apiVersion: v1
kind: Pod
metadata:
  name: foobar
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: foo-config
  restartPolicy: Never

Pod bereitstellen kubectl apply -f test.yaml

kubectl logs foobarAusgabe überprüfen :

xx.ff-bar=1234

ConfigMap erlaubt '-', '_' oder '.'

Eifrig
quelle
0

Während die meisten Shell das Festlegen von Umgebungsvariablen nicht zulassen (wie in anderen Antworten erwähnt), können Sie bei Bedarf andere Programme mit nicht standardmäßigen Umgebungsvariablen ausführen env(1).

Löschen Sie beispielsweise die gesamte Umgebung, setzen Sie Strange.Env:Varden Wert foound führen Sie das Perl-Programm aus, das ihn druckt:

env -i Strange.Env:Var=foo perl -MData::Dumper -E 'say Dumper(\%ENV)'

wird gedruckt

$VAR1 = {
          'Strange.Env:Var' => 'foo'
        };
Matija Nalis
quelle