포인트가 포함된 변수를 내보내는 방법 다음을 시도하면 "잘못된 변수 이름"이라는 메시지가 나타납니다.
export my.home=/tmp/someDir
-ksh: my.home=/tmp/someDir: invalid variable name
메타문자 도트(.)를 이스케이프 처리해도 도움이 되지 않습니다.
$ export my\.home=/tmp/someDir
export: my.home=/tmp/someDir: is not an identifier
답변1
최소한 bash
매뉴얼 페이지의 경우 내보내기 구문은 다음과 같이 정의됩니다.
export [-fn] [name[=word]] ...
또한 "이름"을 다음과 같이 정의합니다.
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.
my.home
따라서 유효한 식별자가 아니기 때문에 실제로 변수를 정의할 수 없습니다 .
나는 귀하의 ksh가 매우 유사한 식별자 정의를 가지고 있으므로 그러한 변수도 허용하지 않는다고 확신합니다. (맨 페이지를 살펴보십시오.)
또한 식별자(및 변수 이름)의 자격을 지정하는 일종의 범용 표준(POSIX?)이 있다고 확신합니다.
어떤 이유로 이런 종류의 변수가 정말로 필요한 경우 다음과 같은 것을 사용할 수 있습니다.
env "my.home=/tmp/someDir" bash
어쨌든 정의하십시오. 그러나 이번에도 일반적인 쉘 구문을 사용하여 액세스할 수는 없습니다. 이 경우 Perl과 같은 다른 언어가 필요할 수 있습니다.
perl -e 'print $ENV{"my.home"}'
예를 들어
env "my.home=/tmp/someDir" perl -le 'print $ENV{"my.home"}'
경로를 인쇄해야합니다.
답변2
환경 변수는 등호 또는 널 바이트(빈 문자열 포함)를 포함하지 않는 모든 이름을 가질 수 있지만 쉘은 환경 변수를 쉘 변수에 매핑하며 대부분의 쉘에서 변수 이름은 ASCII 영숫자 문자로 제한됩니다 _
. 첫 번째 문자는 " t는 숫자일 수 있습니다(위치 매개변수 및 , $*
, $-
, $@
...와 같은 기타 특수 매개변수 제외(해당 환경 변수에 매핑되지 않음)). 또한 일부 변수는 다음과 같습니다.예약/특별쉘을 통해/쉘로.
예외:
셸
rc
및 그 파생물은 빈 문자열을 제외한 모든 이름은 물론 숫자이거나 문자를 포함하는 이름을 지원합니다es
( 항상 모든 변수를 환경으로 내보내고 , , ... 와 같은 특수 변수를 처리합니다 ).akanga
=
*
status
pid
; '%$£"' = test ; echo $'%$£"' test ; '' = x zero-length variable name ;
그러나 실행 명령의 컨텍스트에서 전달되면 이름에 숫자가 포함되지 않은 변수 또는 배열에 대해 자체 인코딩을 사용합니다.
$ 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
및 (yash
단일 바이트 문자에만 해당) ASCII 문자뿐만 아니라 현재 로케일의 숫자를 지원합니다.zsh
bash
$ Stéphane=1 $ echo "$Stéphane" 1
이러한 쉘에서는 대부분의 문자를 알파로 처리하도록 로케일을 변경할 수 있지만 ASCII 문자(예: )의 경우는 그렇지 않습니다 . 문자라고 속이거나 생각할 수 있지만 해당 문자 나 다른
.
ASCII 문자(변수 이름에서) 는 그렇지 않습니다. glob과 같은 문자는 에서 허용됩니다 .zsh
ksh
£
.
[[:alpha:]]
ksh93
이름에 점이 포함된 특수 변수(예: )가 있지만${.sh.version}
이러한 변수는 환경 변수에 매핑되지 않으며 특수합니다. 이는.
다른 변수와 충돌하지 않도록 하기 위한 것입니다. 호출하기로 선택하면$sh_version
이미 해당 변수를 사용하는 스크립트가 중단될 수 있습니다(예를 들어zsh
해당 변수$path
또는$commands
특수 배열/해시 변수(a la csh)가 일부 스크립트를 중단시키는 문제가 있는 방법을 참조하세요).
이러한 변수를 지원하지 않는 쉘 외에도 일부 쉘(예: pdksh/mksh)도 지원합니다.제거하다받은 환경에서 이를 제거하십시오( bash
이름이 비어 있는 환경 문자열을 제거 ash
하고 문자가 없는 환경 문자열을 ksh
제거하십시오 ).bash
=
$ 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 %%%
%%%
대체로 대부분의 셸에서 지원되는 변수 이름을 고수하는 것이 가장 좋습니다. 환경 변수에는 대문자를 사용하고(내보내지 않은 셸 변수에는 소문자 또는 대소문자 혼합) 셸별 변수 이름(예: , , )을 사용하지 않는 것이 IFS
가장 PS1
좋습니다 BASH_VERSION
. ..).
이러한 변수를 지원하지 않지만 삭제하지 않는 셸에서 이러한 변수를 설정해야 하는 경우 직접 다시 수행할 수 있습니다. 예를 들면 다음과 같습니다.
#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"
(물론 도움이 되지 않는 스크립트 중간에 이 작업을 수행해야 하는 경우에는 다음을 볼 수 있습니다.그 방법다시 실행하여 쉘 실행 환경을 저장하고 복원합니다. 또는 디버거 방법을 사용해 보세요.
gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"
(이것은 Linux amd64 zsh
, , yash
, csh
및 에서는 작동하는 것 같지만 tcsh
제가 시도한 다른 쉘( mksh
, ksh93
, , bash
, dash
)에서는 작동하지 않습니다.)
답변3
다른 게시물에서 지적했듯이 대부분의 일반적인 쉘에서는 이름에 마침표가 있는 환경 변수 설정을 허용하지 않습니다. 그러나 특히 Docker 및 호출 프로그램과 관련하여 소프트웨어에 마침표가 포함된 키 값이 필요한 경우가 있음을 발견했습니다.
그러나 각 경우에 이러한 키-값 쌍은 환경 변수 이외의 수단을 통해 프로그램에 전달될 수 있습니다. 예를 들어 Ant에서는 "-propertyfile(filename)"을 사용하여 속성 파일 형식으로 키 값 집합을 전달할 수 있습니다. Confd는 "-백엔드 파일 -파일(yaml 파일)"을 허용합니다.
"C__any_value='my.property.key=the value'" 형식으로 환경 변수를 전달했습니다. 그런 다음 프로그램 호출을 전환하여 먼저 파일을 생성합니다.
set | awk -- 'BEGIN { FS="'\''" } /^C__/ {print $2}' > my-key-values.txt
Borne Shell에서 이 set
명령은 각 속성을 다음 형식의 별도 줄에 출력합니다.
C__any_value='my.property.key=the value'
이 awk
명령은 시작하는 환경 변수만 처리 C__
한 다음 작은따옴표 안에 포함된 값을 추출합니다.
이 방법을 사용하려면 핸들러에서 요구하는 정확한 형식으로 환경 변수 값을 설정해야 합니다. 또한 속성 값이나 키에 작은따옴표가 포함된 경우 awk 필드 구분 기호를 발생하지 않을 문자로 변경하고 해당 문자로 값을 래핑해야 합니다. 예를 들어 %
구분 기호로 사용됩니다.
$ C__1="%my.key=the'value%"
$ set | awk -- 'BEGIN { FS="%" } /^C__/ {print $2}'
my.key=the'"'"'value
(정확한 출력은 셸에 따라 다릅니다.) 이스케이프된 따옴표를 디코딩하려면 추가 단계를 수행해야 합니다.
답변4
@michas의 답변은 매우 정확하지만 export
점 환경 이름을 사용하여 함수를 모의하도록 확장할 수 있습니다.
exec
이러한 변수를 "내보내려면" 현재 쉘에서 명령을 사용할 수 있습니다 env
. 예를 들어 test.env=foo
변수를 내보내려면 다음을 사용합니다.
exec env "test.env=foo" $SHELL
Exec은 현재 셸을 새 프로세스로 대체합니다. 여기서 새 프로세스는 $SHELL
추가 환경 변수 test.env
(에서 추가됨 env "test.env=foo"
)가 있는 현재 셸( )의 새 인스턴스가 됩니다. 따라서 이 명령을 실행한 후 다음과 같은 프로세스에서 액세스할 수 있습니다.
perl -e 'print $ENV{"test.env"}'