쉘 변수 이름에 하이픈이나 대시 (-)가 포함될 수 있습니까?


38

-쉘의 변수에서 사용할 수 없습니다 . 명명 된 변수에 의존하는 하나의 스크립트가 있기 때문에 그것을 사용할 수있는 방법이 있습니까?

$export a-b=c
-bash: export: `a-b=c': not a valid identifier

$export a_b=c

먼저 주어진 오류를 던지고 두 번째는 잘 작동합니다.



쉘은 일반적으로 그러한 변수 이름을 허용하지 않습니다. 변수를 comand의 환경에로드하는 사용자 정의 C 프로그램을 사용하더라도 쉘을 우회해야합니다. 이 기능을 고칠 수 없습니까 (보안 위험 가능성이있을지라도)?
vonbrand

답변:


47

-변수 이름으로 허용되는 Bourne 스타일의 쉘을 본 적이 없습니다 . ASCII 문자 (어쨌든) _와 숫자 만 지원되며 첫 문자는 숫자가 아니어야합니다.

쉘 제한과 일치하지 않는 환경 변수가 필요한 프로그램이 있으면 프로그램으로 시작하십시오 env.

env 'strange-name=some value' myprogram

일부 쉘 (예 : modern dash , mksh, zsh)은 환경에서 이름이 마음에 들지 않는 변수를 제거합니다. ( Shellshock 은 사람들이 환경 변수 이름에 대해 더 신중하게 만들었으므로 시간이 지남에 따라 제한이 더 엄격 해지지는 않을 것입니다.) 이름에 특수 문자가 포함 된 변수를 프로그램에 전달해야하는 경우 직접 전달하십시오. 사이에 쉘 env 'strange-name=some value' sh -c'…; myprogram'이 없으면 (작동하거나 작동하지 않을 수 있음).


더 이상 작동하지 않습니다.
Jesse Glick

4
@JesseGlick 그렇습니다. (당신의 의견은 "작동하지 않음"을 정의한 경우 : 어떤 데이터로, 원하는 효과 대신 효과가 무엇입니까? 그리고 env어떤 운영 체제에서 어떤 구현 을 사용했는지 말한 경우 유용합니다 .)
Gilles 'SO- 악의 '

죄송합니다. envfrom coreutils, shfrom dash:의 모든 업데이트가있는 Ubuntu Yakkety는 env 'with-dashes=value' bash -c 'env | fgrep dashes'작동하지만 env 'with-dashes=value' sh -c 'env | fgrep dashes'아무 것도 인쇄하지 않습니다. 즉, env그 자체로는 문제가 없지만 Dash는 이러한 변수를 구체적으로 차단하는 것 같습니다. 따라서 문제의 프로그램이 일반적인 #!/bin/sh헤더가 있는 쉘 랩퍼를 통해 시작 되면 이러한 변수를 전달할 확실한 방법이 없습니다. 해결 방법 예
Jesse Glick

@JesseGlick 변수를 제거하는 대시입니다. env사이에 쉘없이이 변수 이름이 필요한 프로그램의 호출 사이트에 더 가깝게 사용해야 합니다. 대시만으로는 이름이 마음에 들지 않는 변수를 제거 할 수 있습니다.
Gilles 'SO- 악한 중지'

1
@JesseGlick하지만 실제로 작동했던 일부 항목이 더 이상 작동하지 않을 수 있다는 것은 사실입니다. shellshock 이후 로 사람들은 변수 이름에 대해 더 보수적이되었으며 대시 는이 답변을 작성한 이후 실제로 변경 되었습니다 (Shellshock의 결과가 아니라, 그러나 같은 줄을 따라 버그를 피하기 위해). 내 답변에 메모를 추가했습니다.
Gilles 'SO- 악한 중지'

15

Bash에서는 불가능합니다.

로부터 정의 의 매뉴얼 페이지 섹션 bash:

name 영숫자 및 밑줄로만 구성되고 알파벳 문자 또는 밑줄로 시작하는 단어입니다. 식별자라고도합니다.

로부터 매개 변수 의 매뉴얼 페이지 섹션 bash:

매개 변수는 값을 저장하는 엔티티입니다. 이름, 숫자 또는 특수 매개 변수 아래 아래에 나열된 특수 문자 중 하나 일 수 있습니다. 변수는 이름으로 표시되는 매개 변수입니다.


2
매뉴얼 페이지의 유용성을 다시 한 번 보여주는 +1
ktf

2
내가 알고있는 오래된 게시물이지만, 새로운 이민자에게 맨 페이지가 상당히 암호가 될 수 있음을 지적하고 싶습니다. 더 나은 설명 / 예제를 찾아야 할 때가 있습니다. 그들이 결코 일어나지 않았다고 말하면 누구나 거짓말을 할 것입니다.
TCZ8

1
@ TCZ8 매뉴얼 페이지가 '암호 적'이라고 생각한 유일한 사람들은 오류 메시지를 읽지 않고 모든 것을 훑어 보는 사람들과 동일한 종류의 사람들과 동일하다고 생각합니다.
Miles Rout

13

간접 참조를 사용하여 하이픈으로 연결된 변수에 액세스 할 수 있습니다.

$ env 'my-hyphenated-variable=hello' /bin/bash
$ name='my-hyphenated-variable'
$ echo ${!name}
hello

1
이 의견을 읽을 때 까지이 기능에 대해 들어 본 적이 없었습니다. 허용 된 답변보다 훨씬 쉬운 솔루션을 제공했습니다.
DrStrangepork

7
이 동작은 최신 버전의 bash에서 비활성화되었습니다. 상황을 철저히 분석하려면 stackoverflow.com/questions/36989263/… 를 참조하십시오 .
Nicolas Dudebout

6

스크립트가 경우에 따라 변수 이름은 하이픈이있는에, 그는 프로그래밍 오류입니다. 변수 이름에 하이픈이 포함되도록 정기적으로 사용하는 도구로 인해 편리한 경우 더 많은 도구를 배워야 할 수도 있습니다.

하이픈을 밑줄로 변환하기 위해 tr 을 사용해 보셨습니까 ?

hyphenated_name="a-b"
unhyphenated_name=$(echo $hyphenated_name | tr '-' '_')
declare -x $unhyphenated_name="some value"

Bash는 함수 이름에 '-'가 표시되도록합니다. 나는 항상 이것을한다. 예를 들면 다음과 같습니다.

function foo-bar() {
   echo "$@"
}

2

대시 ( -) 문자는 분리 문자이며 변수 이름의 일부로 사용할 수 없습니다. 인용 된 변수로 이것을 해킹하는 방법이 있지만 파싱하는 것은 실제로 문제가 있습니다. bash의 변수 이름과 관련하여 중괄호, 괄호, 연산자 문자 및 따옴표와 같이 특별한 의미를 가진 다른 문자도 있습니다. (예 : {}()=+-&'"기타)

실제로 스크립트를 작성할 다른 패러다임을 찾아야한다고 제안합니다. "변수 변수 이름"에 대한 다른 언어의 생각이있을 수 있습니다. 쉘 스크립트에서는 일반적으로 좋은 생각이 아닙니다.

당신이 이것을 편집하거나 당신의 상황과 당신이 달성하려는 것을 자세하게 설명하는 새로운 질문을한다면, 우리는 그것을 스크립팅하는 좋은 방법을 제안 할 수 있습니다.


2

Bash 매뉴얼은 "이름"을 다음과 같이 정의합니다.

문자, 숫자 및 밑줄로만 구성되고 문자 나 밑줄로 시작하는 '단어'. '이름'은 쉘 변수 및 함수 이름으로 사용됩니다. '식별자'라고도합니다.

이름에 하이픈을 사용할 수 없습니다.


0

대부분의 쉘은 변수 이름에 대해 az, AZ, 0-9 및 _ 만 지원합니다. 이 페이지의 두 번째 항목을 읽으십시오 .


0

env와 sed로 놀 수 있습니다.

예를 들어,이 변수 'ELASTICSEARCH_CLUSTER-NODES'를 읽어야했습니다.
env 명령은 다음을 출력합니다.

~ $ env
ELASTICSEARCH_CLUSTER-NODES=elasticsearch:9200
JAVA_ALPINE_VERSION=8.212.04-r0
HOSTNAME=17eb9e7fec4c
...

변수를 추출하려면 :

ESHOST=`env | sed -n 's/ELASTICSEARCH_CLUSTER-NODES=\(.*\)/\1/p'`

-1

bash 변수에는 문자, 숫자 및 밑줄 만 사용할 수 있다고 생각합니다. 이것은 많은 프로그래밍 언어의 경우입니다 (자바 스크립트는 예외 임).

스크립트가 이러한 유형의 변수 이름에 의존하지 않는 것이 좋습니다.

실제로 변수 이름을 다른 이름으로 바꿀 수있는 방식으로 프로그래밍해야하지만 차이가 없습니다. 일반적으로 변수 이름은 변수에 포함 된 내용을 설명해야합니다. 이렇게하면 디버깅이 훨씬 쉬워집니다. 그렇지 않다면 코드를 파악하려는 다음 개발자를위한 것입니다.


-1

env명령을 사용하여 히피 "-"로 환경 변수를 설정 및 설정 해제 할 수 있습니다 .

설정하려면 env를 사용하여 명령을 실행해야합니다 env command. 이런 식으로 변수를 전달합니다.

env a-b=c command

그것이 작동하는 것을 참조하십시오 :

env a-b=c env

또는 더 명확하게하기 위해 :

env a-b=c env|grep 'a-b'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.