명령줄에서 환경 변수를 설정하고 명령에 표시하려면 어떻게 해야 합니까?

명령줄에서 환경 변수를 설정하고 명령에 표시하려면 어떻게 해야 합니까?

내가 달리면

export TEST=foo
echo $TEST

foo를 출력합니다.

내가 달리면

TEST=foo echo $TEST

아니요. 내보내기나 스크립트를 사용하지 않고 이 기능을 얻으려면 어떻게 해야 합니까?

답변1

이는 쉘이 명령줄에서 변수를 확장하기 때문입니다.앞으로실제로 명령을 실행하지만 이 시점에서는 변수가 존재하지 않습니다. 당신이 사용하는 경우

TEST=foo; echo $TEST

작동합니다.

export이후에 실행되는 명령의 환경에 변수가 나타나게 됩니다(bash 에서 이것이 어떻게 작동하는지에 대한 정보는 참조 help export). 하나의 명령 환경에만 변수가 표시되어야 하는 경우 시도한 방법을 사용하십시오.

TEST=foo your-application

쉘 구문은 이를 다음과 같이 설명합니다.기능적으로다음과 동일:

export TEST=foo
your-application
unset TEST

바라보다사양더 알아보기.

흥미롭게도 이 export명령은 변수의 내보내기 플래그를 토글합니다.이름. 그렇다면 다음과 같이 하세요.

unset TEST
export TEST
TEST="foo"

TEST내보내기 시 정의되지 않은 경우에도 내보내집니다. 그러나 unset내보낸 속성은 여기서 제거해야 합니다.

답변2

당신이 갖고 싶어하는 것 같아요껍데기변수는 환경 변수가 아닌 제한된 범위를 갖습니다. 환경 변수는 명령에 전달된 문자열 목록입니다.처형된.

존재하다

var=value echo whatever

var=value문자열을 에코 수신 환경에 전달합니다 . 그러나 echo환경 목록에는 아무 작업도 수행되지 않으며 대부분의 셸에는 echo어쨌든 내장되어 있으므로 그렇게 하지 않습니다.처형된.

당신이 썼다면

var=value sh -c 'echo "$var"'

그것은 또 다른 이야기입니다. 여기서는 명령을 전달하고 var=value해당 환경 을 사용하게 됩니다. 쉘은 환경에서 받은 모든 변수를 쉘 변수로 변환하므로 받은 환경 변수는 변수 로 변환되고 해당 명령줄에서 확장하면 환경이 기본적으로 상속 되므로 가 됩니다 . 또한 해당 환경에서 수신되지만(또는 실행되는 경우) 환경에 대해서는 신경 쓰지 않습니다.shshvarsh$varechoecho valueechovar=valueecho

이제 제가 생각하는 것처럼 쉘 변수의 범위를 제한하려는 경우 몇 가지 가능한 방법이 있습니다.

휴대용(Bourne 및 POSIX):

(var=value; echo "1: $var"); echo "2: $var"

(...) 위는 서브쉘(대부분의 쉘에서 새로운 쉘 프로세스)을 시작하므로 여기에 선언된 모든 변수는 해당 서브쉘에만 영향을 미치므로 위의 코드에서 "1: value" 및 " 2:" 또는 " 2: 이전에 설정된 모든 변수".

대부분의 Bourne형 쉘의 경우(참조지역 변수를 정의하기 위해 "local" 키워드를 지원하는 쉘 목록), 함수와 "로컬" 내장 기능을 사용할 수 있습니다.

f() {
  local var
  var=value
  echo "1: $var"
}
f
echo "2: $var"

zsh를 사용하면 다음을 사용할 수 있습니다.익명 함수일반 함수와 마찬가지로 로컬 범위를 가질 수 있습니다.

(){ local var=value; echo "1: $var"; }; echo "2: $var"

또는:

function { local var=value; echo "1: $var"; }; echo "2: $var"

이 트릭은 bash 및 zsh에도 적용됩니다(ash, pdksh 또는 AT&T ksh에는 적용되지 않음).

var=value eval 'echo "1: $var"'; echo "2: $var"

더 많은 쉘( dash, mksh, ) yash에서 작동하지만 작동하지 않는 변형 ( / 에뮬레이션 zsh제외 ):shksh

var=value command eval 'echo "1: $var"'; echo "2: $var"

( POSIX 셸의 command특수 내장 함수(여기) 앞에서 이를 사용하면 eval특수성이 제거됩니다(여기서 선행 변수 할당은 반환 후에도 유효합니다).

fish셸을 사용하면 변수를 begin.. end블록에 로컬로 설정할 수 있습니다.

begin
  set -l var value
  echo 1: $var
end
echo 2: $var

mksh(그리고 곧 zsh를 사용 하면 ${|cmd}로컬 범위도 가질 수 있는 이 구성을 남용하여 $REPLY다음 범위에서 설정하지 않도록 하여 null로 확장되도록 할 수 있습니다.

${|local var=value; echo "$var"}; echo "$var"

엄밀히 말하면 이것은 전적으로 사실이 아닙니다. 일부 구현은 지역화된 환경 변수( LANG, LOCPATH, LC_*...)에 관심을 갖고, GNU 구현은 POSIXLY_CORRECT환경 변수( GNU 시스템과 달리) env echo --version에 관심을 갖습니다.env POSIXLY_CORRECT=1 echo --version

답변3

올바르게 수행하고 있지만 bash 구문은 쉽게 오해됩니다. 이렇게 하면 env var를 가져온 다음 인쇄하게 echo $TEST될 것이라고 생각할 수도 있지만 그렇지 않습니다. 그래서 주어진echoTEST

export TEST=123

그 다음에

TEST=456 echo $TEST

다음 순서가 포함됩니다.

  1. 쉘은 전체 명령줄을 구문 분석하고 모든 변수 대체를 수행하므로 명령줄은 다음과 같습니다.

    TEST=456 echo 123
    
  2. 명령 이전에 임시 변수 세트를 생성하므로 현재 값을 저장하고 TEST이제 명령줄을 456으로 덮어씁니다.

    echo 123
    
  3. 나머지 명령을 실행합니다. 이 경우 표준 출력에 123을 인쇄합니다(따라서 나머지 쉘 명령에는 임시 값이 사용되지도 않습니다 TEST).

  4. 가치를 회복시켜준다TEST

대신 변수 대체를 포함하지 않으므로 printenv를 사용하십시오.

>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>

답변4

이미 발견한 바와 같이, Bash에서는 TEST=456 echo $TEST쉘이 현재 해석하고 있는 동일한 행의 변수에 액세스하고 있기 때문에 예상대로 작동하지 않습니다. 하지만 걱정하지 마세요. 변수는 현재 명령이 지속되는 동안 설정됩니다. 이를 확인하려면 다음을 수행할 수 있습니다.

show () { echo "${!1}" ;}
TEST=456 show TEST

관련 정보