Caratteri consentiti nei nomi delle variabili di ambiente Linux


143

Quali caratteri sono ammessi nei nomi delle variabili di ambiente Linux? La mia rapida ricerca delle pagine man e del web ha prodotto solo informazioni su come lavorare con le variabili, ma non sui nomi consentiti.

Ho un programma Java che richiede una variabile d'ambiente definita contenente un punto, come com.example.fancyproperty. Con Windows posso impostare quella variabile, ma non ho avuto fortuna impostandola su Linux (provato su SuSE e Ubuntu). È consentito anche quel nome di variabile?


3
Fortunatamente, ho scoperto che il programma è altrettanto felice con una proprietà di sistema Java (dichiarata con -Dun'opzione da riga di comando), quindi funziona ora. Ovviamente il programma guarda in entrambi i set di variabili senza dirmelo. Ma sono ancora curioso di sapere quali nomi di variabili di ambiente sono ammessi.
Christian Semrau

@AleksandrDubinsky L'ho eliminato. Questo è simile ma sulla definizione di alias non esattamente variabili d'ambiente stackoverflow.com/questions/24690640/…
Lime

1
Se stai usando Spring , anche SystemEnvironmentPropertySource predefinito cercherà com_example_fancypropertye COM_EXAMPLE_FANCYPROPERTY.
Aleksandr Dubinsky

Risposte:


203

Da The Open Group :

Queste stringhe hanno la forma nome = valore; i nomi non devono contenere il carattere '='. Affinché i valori siano portabili su sistemi conformi a IEEE Std 1003.1-2001, il valore deve essere composto da caratteri del set di caratteri portatile ( tranne NUL e come indicato di seguito ).

Quindi i nomi possono contenere qualsiasi carattere tranne = e NUL, ma:

I nomi delle variabili di ambiente utilizzati dalle utility nel volume Shell and Utilities di IEEE Std 1003.1-2001 sono costituiti esclusivamente da lettere maiuscole, cifre e "_" (trattino basso) dai caratteri definiti nel set di caratteri portatile e non iniziano con una cifra . Altri caratteri possono essere consentiti da un'implementazione; le domande devono tollerare la presenza di tali nomi.

Quindi, sebbene i nomi possano essere validi, la shell potrebbe non supportare nulla oltre a lettere, numeri e caratteri di sottolineatura.


8
Solo controllo: la seconda citazione non è normativa: osserva semplicemente che le variabili che POSIX definisce speciali per le sue utility [a-zA-Z_][a-zA-Z0-9_]*(implicitamente suggerendo che questo modulo è più sano), ma le specifiche effettive (citazione 1) richiedono che tutte le implementazioni supportino qualsiasi cosa ma =e NUL?
Ciro Santilli 21 冠状 病 六四 事件 法轮功

3
Inoltre, il "set di caratteri portatile" pubs.opengroup.org/onlinepubs/000095399/basedefs/… contiene cose come spazi e non stampabili: quindi possiamo usare queste cose o no?
Ciro Santilli 21 冠状 病 六四 事件 法轮功

3
Questo è esattamente ciò che osservo. Shell non ama i caratteri speciali come parte del nome di una variabile. Tuttavia, quando un programma o uno script (ad esempio java o perl) inizializza una variabile con caratteri speciali nel suo nome e chiama un altro eseguibile (un processo figlio), quest'ultimo può accedere a quella variabile senza problemi.
oᴉɹǝɥɔ

1
@checksum, MAIUSCOLO viene esplicitamente specificato per i nomi delle variabili con significato per gli strumenti specificati da POSIX, inclusa la shell; i nomi con almeno un carattere minuscolo sono esplicitamente riservati per l'uso dell'applicazione. Pertanto, la migliore pratica consiste effettivamente nell'includere almeno un carattere minuscolo nei nomi delle variabili delle applicazioni per garantire che non si stia sovrascrivendo involontariamente (poiché l'impostazione di una variabile di shell sovrascriverà qualsiasi variabile di ambiente con nome simile) una variabile con significato il sistema. Vedi pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Charles Duffy

2
@CiroSantilli 烏坎 事件 2016 六四 事件 法轮功, puoi usarli nelle variabili d'ambiente; non è possibile utilizzarli nelle variabili shell e tali variabili di ambiente non sono garantite come accessibili dalla shell.
Charles Duffy,

37

Gli standard POSIX sulla sezione shell di IEEE Std 1003.1-2008 / IEEE POSIX P1003.2 / ISO 9945.2 Shell e strumenti standard non definiscono la convenzione lessicale per i nomi delle variabili, tuttavia uno sguardo superficiale alla fonte rivela che utilizza qualcosa di simile a

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

(Modifica: Aggiunto carattere di sottolineatura mancante nella seconda classe di caratteri.)

Una breve nota, poiché alcune shell non supportano il + in regex, una regex potenzialmente più portatile può essere:

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


4
Grazie Aiden. Penso che manchi un carattere di sottolineatura nella seconda serie di parentesi quadre: Probabilmente dovrebbe leggere: [a-zA-Z_][a-zA-Z0-9_]* Per quelli come me che trovano il riferimento a bash-4.1 un po 'vago (616'000 righe di codice), ecco alcuni suggerimenti per trova le righe di codice rilevanti: subst.c: param_expand(), in the default case-> general.h:/ * Definisci esattamente in cosa consiste un identificatore di shell legale. * / #define legal_variable_starter (c) (ISALPHA (c) || ​​(c == ' ')) #define legal_variable_char (c) (ISALNUM (c) || ​​c == ' ')
Chris

3
Non è necessario quel plus nella prima classe di personaggi.
scravy

2
@scravy true, anche se ho preso il regexp dalla fonte, quindi terrò il + in.
Aiden Bell,

4
POSIX definisce: 3.231 Nome a word consisting solely of underscores, digits, and alphabetics from the portable character set. The first character of a name is not a digit .

Non nella sezione shell, ma ci sono assolutamente standard POSIX che includono convenzioni per la denominazione delle variabili di ambiente (e in realtà discutono nomi riservati per l'uso della shell). Vedi pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Charles Duffy

12

I miei test rapidi hanno dimostrato che sostanzialmente seguono le stesse regole dei nomi delle variabili C, vale a dire

  1. az, AZ _e 0-9
  2. Potrebbe NON iniziare con un numero

Quindi questo esclude .al loro interno. Viene accreditato qualsiasi nome di variabile illegale unknown command.

Questo è stato testato in ZSH, che è principalmente compatibile con BASH.


6

Dipende da cosa intendi per "consentito".

Ignorando Windows per il nonce:

L'ambiente è un array di stringhe, passato alla funzione principale di un programma. Se leggi execve (2), non vedrai requisiti o limiti su queste stringhe oltre alla null-termination.

Per convenzione, ogni stringa è composta da NAME = valore. Non esiste una convenzione di quotazione, quindi non puoi avere un '=' nel nome in questa convenzione.

Gli umani normali impostano queste corde discutendole con il loro guscio. Ogni shell ha le sue idee su cosa sono i nomi variabili validi, quindi devi leggere la pagina man per la shell del momento per vedere cosa ne pensa.

In genere, cose come com.baseball.spit = fleagh sono proprietà di sistema Java e se un programma Java è disposto a ricorrere all'ambiente, è meglio specificarle con -D.


Avrei dovuto prima giungere alla conclusione che la variabile è formattata come una proprietà di sistema Java, invece di provare a impostarla come variabile di ambiente.
Christian Semrau,


4

SI, PUOI FARLO.

Utilizzare exece envcomando per implementare questa scena.

Dispositivo di prova in Docker

docker run -it --rm alpine:3.10

Esegui comando nel contenitore:

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

Verifica variabili d'ambiente:

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=/

Utilizzare ps auxper verificare che il PID non sia stato modificato

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

Utilizzare pythonper verificare la variabile di ambiente

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

OUTPUT è happy-variable-name.

Cosa succede?

  1. Shell chiama builtin exec
  2. La shell integrata exec chiama syscall.exec crea il processo 'env' per sostituire la shell corrente
  3. chiama enyscall.execvp crea processo '/ bin / sh' per sostituire il processo env

Un altro modo

  • Immagine Docker

Se si utilizza la finestra mobile, è possibile impostare la variabile in File Docker

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

Se stai usando kubernetes, puoi impostare la variabile tramite ConfigMap

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

Distribuire pod kubectl apply -f test.yaml

Verifica kubectl logs foobaroutput:

xx.ff-bar=1234

ConfigMap consente '-', '_' o '.'


0

Sebbene la maggior parte della shell non consenta di impostare variabili di ambiente (come menzionato in altre risposte), se ne hai bisogno puoi eseguire altri programmi con variabili di ambiente non standard usando env(1).

Ad esempio, cancellando tutto l'ambiente e impostando il Strange.Env:Varvalore fooed eseguendo il programma perl che lo stampa:

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

stamperà

$VAR1 = {
          'Strange.Env:Var' => 'foo'
        };
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.