Linux 환경 변수 이름에서 허용되는 문자


143

Linux 환경 변수 이름에는 어떤 문자가 허용됩니까? 맨 페이지와 웹을 커서로 검색하면 변수 작업 방법에 대한 정보 만 생성되었지만 어떤 이름은 허용되지 않습니다.

점과 같은 정의 된 환경 변수가 필요한 Java 프로그램이 com.example.fancyproperty있습니다. Windows에서는 해당 변수를 설정할 수 있지만 Linux (SuSE 및 Ubuntu에서 시도)에서 변수를 설정하는 것은 운이 없었습니다. 그 변수 이름도 허용됩니까?


3
운 좋게도 프로그램이 Java 시스템 속성 ( -D명령 줄 옵션으로 선언)에 만족한다는 것을 알았 으므로 지금 작동합니다. 분명히 프로그램은 나에게 알리지 않고 두 변수 세트를 모두 찾습니다. 그러나 여전히 어떤 환경 변수 이름이 허용되는지 궁금합니다.
Christian Semrau

@AleksandrDubinsky 삭제했습니다. 이것은 비슷하지만 별명 정의에 대해서는 정확히 환경 변수가 아닙니다. stackoverflow.com/questions/24690640/…
Lime

1
당신이 사용하는 경우 , 디폴트 SystemEnvironmentPropertySource도 찾아 볼 것 com_example_fancyproperty하고 COM_EXAMPLE_FANCYPROPERTY.
Aleksandr Dubinsky

답변:


203

에서 사용되는 The Open Group :

이 문자열은 name = value 형식입니다. 이름은 문자 '='를 포함 할 수 없습니다. IEEE Std 1003.1-2001을 준수하는 시스템에서 값을 이식 할 수 있으려면 값을 이식 가능한 문자 세트의 문자로 구성해야합니다 ( NUL 제외 및 아래에 표시된대로 ).

따라서 이름에는 = 및 NUL을 제외한 모든 문자가 포함될 수 있지만

IEEE Std 1003.1-2001의 쉘 및 유틸리티 볼륨에서 유틸리티가 사용하는 환경 변수 이름은 대문자, 숫자 및 휴대용 문자 세트에 정의 된 문자 의 '_'(밑줄)로만 구성되며 숫자로 시작하지 않습니다 . 구현시 다른 문자가 허용 될 수 있습니다. 응용 프로그램은 그러한 이름의 존재를 용인해야합니다.

따라서 이름은 유효하지만 쉘은 문자, 숫자 및 밑줄 이외의 것을 지원하지 않을 수 있습니다.


8
그냥 확인 : 두 번째 인용은 비 규범 적입니다 : POSIX가 유틸리티를 위해 특별하다고 정의한 변수가 [a-zA-Z_][a-zA-Z0-9_]*(암시 적 으로이 형식이 더 암시적임을 암시합니다) 실제로 관찰 하지만 실제 사양 (인용 부호 1) 모든 구현을 요구 하지만 =그리고 NUL?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3
또한 "휴대용 문자 세트" pubs.opengroup.org/onlinepubs/000095399/basedefs/… 에는 공백이나 인쇄 할 수없는 것들이 포함되어 있습니다.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3
이것이 바로 내가 관찰 한 것입니다. 쉘은 변수 이름의 일부로 특수 문자를 좋아하지 않습니다. 그러나 한 프로그램이나 스크립트 (예 : java 또는 perl)가 이름에 특수 문자를 사용하여 변수를 초기화하고 다른 실행 파일 (자식 프로세스)을 호출하면 후자의 실행 파일이 문제없이 해당 변수에 액세스 할 수 있습니다.
oᴉɹǝɥɔ

1
@checksum, UPPERCASE는 쉘을 포함하여 POSIX 지정 도구를 의미하는 변수 이름에 대해 명시 적으로 지정됩니다. 소문자가 하나 이상인 이름은 응용 프로그램 사용을 위해 명시 적으로 예약되어 있습니다. 따라서 모범 사례는 실제로 응용 프로그램의 변수 이름에 적어도 하나의 소문자를 포함하여 의도하지 않게 셸 변수를 설정하면 비슷한 이름의 환경 변수를 덮어 씁니다. 시스템. pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Charles Duffy

2
@CiroSantilli 烏坎 事件 2016 六四 事件 法轮功, 환경 변수에서 사용할 수 있습니다. 당신은 할 수없는 쉘 변수를 사용하고, 그 환경 변수는 쉘에서 액세스 할 수 보장 할 수 없습니다.
Charles Duffy

37

IEEE Std 1003.1-2008 / IEEE POSIX P1003.2 / ISO 9945.2의 쉘 섹션에있는 POSIX 표준 쉘 및 도구 표준은 변수 이름에 대한 어휘 규칙을 정의하지 않지만 소스를 살펴보면 다음과 유사한 것을 사용합니다.

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

(편집 : 두 번째 문자 클래스에 누락 된 밑줄이 추가되었습니다.)

일부 쉘은 정규식에서 +를 지원하지 않으므로 잠재적으로 더 이식 가능한 정규식은 다음과 같습니다.

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


4
고마워, 에이든 나는 두 번째 대괄호 세트에 밑줄이 없다고 생각합니다. 아마도 읽을 것입니다 : [a-zA-Z_][a-zA-Z0-9_]* bash-4.1에 대한 참조를 모호한 (616'000 줄의 코드) 찾는 저와 같은 사람들에게는 다음과 같은 힌트가 있습니다. 관련 코드 줄을 찾으십시오 subst.c: param_expand(), in the default case.-> general.h:/ * 유효한 쉘 식별자로 구성된 것을 정확하게 정의하십시오. * / #define legal_variable_starter (c) (ISALPHA (c) || ​​(c == ' ')) #define legal_variable_char (c) (ISALNUM (c) || ​​c == ' ')
Chris

3
첫 번째 문자 클래스에는 플러스가 필요하지 않습니다.
scravy

2
@scravy true, 소스에서 정규 표현식을 가져 와서 +를 계속 사용할 것입니다.
Aiden Bell

4
POSIX는 다음을 정의합니다. 3.231 이름 a word consisting solely of underscores, digits, and alphabetics from the portable character set. The first character of a name is not a digit .

쉘 섹션에는 없지만 환경 변수 이름 지정 규칙이 포함 된 POSIX 표준이 있습니다 (실제로 쉘 사용을 위해 예약 된 이름에 대해 설명합니다). 참조 pubs.opengroup.org/onlinepubs/9699919799/basedefs/...
찰스 더피에게

12

내 빠른 테스트는 기본적으로 C 변수 이름과 동일한 규칙, 즉

  1. az, AZ _및 0-9
  2. 숫자로 시작할 수 없습니다

따라서 이것은 .내부를 제외 합니다. 불법 변수 이름은로 인정됩니다 unknown command.

이것은 주로 BASH 호환 ZSH에서 테스트되었습니다.


6

'허용'이라는 말의 의미에 따라 다릅니다.

nonce에 대한 Windows 무시 :

환경은 문자열 배열이며 프로그램의 주요 기능으로 전달됩니다. execve (2)를 읽으면 null 종료 이외의 문자열에 대한 요구 사항이나 제한이 없습니다.

일반적으로 각 문자열은 NAME = value로 구성됩니다. 인용 규칙이 없으므로이 규칙에서 이름에 '='를 사용할 수 없습니다.

보통의 사람들은이 끈을 조개 껍질로 토론하여이 끈을 설정합니다. 각 쉘에는 유효한 변수 NAME이 무엇인지에 대한 자체 아이디어가 있으므로 쉘의 생각을 보려면 쉘 페이지의 맨 페이지를 읽어야합니다.

일반적으로 com.baseball.spit = fleagh와 같은 것은 Java 시스템 특성이며 일부 Java 프로그램이 환경으로 되돌아 갈 것인지의 여부에 관계없이 -D로 지정하는 것이 좋습니다.


변수 변수를 환경 변수로 설정하는 대신 Java 시스템 특성처럼 형식화되었다는 결론에 도달해야했습니다.
기독교 Semrau


4

그렇습니다, 당신은 그것을 할 수 있습니다.

이 장면을 구현 하려면 execenv명령을 사용하십시오 .

Docker의 테스트 픽스처

docker run -it --rm alpine:3.10

컨테이너에서 명령을 실행하십시오.

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

환경 변수를 확인하십시오.

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

ps auxPID가 변경되지 않았는지 확인하는 데 사용

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

python환경 변수 확인에 사용

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

출력은 happy-variable-name입니다.

무슨 일이야?

  1. 쉘 호출 내장 exec
  2. 셸 내장 exec 호출 syscall.exec는 현재 셸을 대체하는 프로세스 'env'를 만듭니다.
  3. env 프로세스 호출 syscall.execvp env 프로세스를 대체하는 프로세스 '/ bin / sh'작성

또 다른 방법

  • 도커 이미지

docker를 사용하는 경우 Dockerfile에서 변수를 설정할 수 있습니다

FROM busybox
ENV xx.f%^&*()$#ff=1234
  • 쿠 버네 티스 구성 맵

kubernetes를 사용하는 경우 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

포드 배포 kubectl apply -f test.yaml

kubectl logs foobar출력 확인 :

xx.ff-bar=1234

ConfigMap은 '-', '_'또는 '.'을 허용합니다.


0

대부분의 쉘은 환경 변수 설정을 허용하지 않지만 (다른 답변에서 언급했듯이) 필요하다면을 사용하여 비표준 환경 변수로 다른 프로그램을 실행할 수 있습니다 env(1).

예를 들어, 모든 환경을 지우고 Strange.Env:Varvalue를 value로 설정 하고 foo이를 인쇄하는 perl 프로그램을 실행하십시오.

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

인쇄합니다

$VAR1 = {
          'Strange.Env:Var' => 'foo'
        };
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.