환경 변수를 설정하는 명령에 변수로 접두사를 사용할 수없는 이유는 무엇입니까?


11

일반적으로 다음과 같이 접두어로 명령에 대한 환경 변수를 설정할 수 있습니다.

hello=hi bash -c 'echo $hello'

또한 변수를 사용하여 다음과 같이 명령 호출의 일부를 대체 할 수 있음을 알고 있습니다.

$ cmd=bash
$ $cmd -c "echo hi" # equivalent to bash -c "echo hi"

환경 변수를 설정하는 명령 앞에 변수를 사용할 수 없다는 것을 알게되어 매우 놀랐습니다. 테스트 사례 :

$ prefix=hello=hi
$ echo $prefix # prints hello=hi
$ $prefix bash -c 'echo $hello'
hello=hi: command not found

변수를 사용하여 환경 변수를 설정할 수없는 이유는 무엇입니까? 접두사 부분은 특별한 부분입니까? eval을 사용하여 작동시킬 수 있었지만 여전히 이유를 이해하지 못합니다. bash 4.4를 사용하고 있습니다.


1
당신이 사용할 수있는 env대신 evalIIRC이 더 안전하지만, 느린이다.
wjandrea

답변:


14

나는 이것이 당신을 잡는 순서의 일부라고 생각합니다.

가변적 인 할당이나 방향 전환이 아닌 단어가 확장됩니다 (쉘 확장 참조). 확장 후에도 단어가 남아 있으면 첫 번째 단어는 명령의 이름으로 간주되고 나머지 단어는 인수입니다.

간단한 명령 확장 섹션 의 Bash 참조 매뉴얼 에 있습니다.

cmd=bash예제에서는 환경 변수가 설정되지 않았으며 bash는 매개 변수 확장을 통해 명령 줄을 처리하고을 남겨 둡니다 bash -c "echo hi".

prefix=hello=hi예제 에서는 첫 번째 패스에 변수 할당이 다시 없으므로 처리는 계속해서 매개 변수 확장으로 진행되어 첫 번째 단어는 hello=hi입니다.

변수 할당이 처리 된 후에는 명령 실행 중에 다시 처리되지 않습니다.

아래의 처리 및 결과를 참조하십시오 set -x.

$ prefix=hello=hi
+ prefix=hello=hi
$ $prefix bash -c 'echo $hello'
+ hello=hi bash -c 'echo $hello'
-bash: hello=hi: command not found
$ hello=42 bash -c 'echo $hello'
+ hello=42
+ bash -c 'echo $hello'
42

"변수 확장"- "환경 변수"의보다 안전한 변형을 위해 다음에 대한 wjandrea의 제안을eval 고려 하십시오env .

prefix=hello=hi
env "$prefix" bash -c 'echo "$hello"'
hi

env환경 변수를 명령에 할당 하는 유틸리티의 주요 기능을 사용하기 때문에 명령 행 변수 할당은 아니지만, 동일한 목표를 달성합니다. $prefix변수 이름 = 값을 제공하는 명령 행 처리 중에 팽창 env에 따라이를 통과 bash.


3
마찬가지로, $foo=bar bash -c ...때문에 작동하지 않습니다 $foo=bar변수 할당 (의 값이 무엇이든하지 않습니다 $foo때문에), $foo=bar적합하지 않습니다 name=value변수 할당에 대한 패턴.
muru December

3

때문에이 $prefix할당되지 않습니다. @Jeff는 더 긴 설명이 있습니다.

대신 함수를 사용하여 비슷한 작업을 수행 할 수 있습니다.

$ prefix() { hello=hi "$@"; }
$ prefix bash -c 'echo "$hello"'
hi

... 원하는 경우 스택을 쌓을 수도 있습니다.

$ foo() { foo=123 "$@"; }
$ bar() { bar=456 "$@"; }
$ foo bar bash -c 'echo "$bar $foo"'
456 123
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.