프로세스가 부모의 환경을 상속한다면 왜 내보내기가 필요한가?


72

본인은 여기 를 목적으로하는 export쉘의 서브 프로세스에 사용할 수있는 변수는 쉘에서 시작하는 것입니다.

그러나 나는 또한 여기여기 에서 "프로세스가 부모 (환경을 시작한 프로세스)로부터 환경을 상속받습니다."라고 읽었습니다 .

이 경우 왜 필요한가 export? 내가 무엇을 놓치고 있습니까?

쉘 변수는 기본적으로 환경의 일부가 아닌가? 차이점은 무엇입니까?

답변:


74

쉘 변수가 환경에 있다고 가정 합니다 . 이것은 올바르지 않습니다. 이 export명령은 환경에 이름을 지정하는 것입니다. 그러므로:

a=1 b=2
export b

현재 $a 은 1과 $b2로 확장 한다는 것을 알고 있지만 하위 프로세스는 a환경의 일부가 아니기 때문에 (현재 쉘에서도) 알지 못합니다 .

몇 가지 유용한 도구 :

  • set: 현재 쉘의 매개 변수를 보는 데 유용합니다.
  • set -k: 환경에서 할당 된 인수 를 설정 합니다. 치다f() { set -k; env; }; f a=1
  • set -a: 쉘이 환경에 설정되는 이름을 입력하도록 지시합니다. export모든 과제 를 하기 전에 퍼팅처럼 . .env에서와 같이 파일에 유용합니다 set -a; . .env; set +a.
  • export: 쉘에게 환경에 이름을 지정하도록 지시합니다. 내보내기와 할당은 완전히 다른 작업입니다.
  • env: 외부 명령으로 상속 된 환경 env에 대해서만 알려줄 수 있으므로 온 전성 검사에 유용합니다.
  • env -i: 서브 프로세스를 시작하기 전에 환경을 지우는 데 유용합니다.

대안 export:

  1. name=val command # 명령 전 할당은 해당 이름을 명령으로 내 보냅니다.
  2. declare/local -x name # 이름을 내 보냅니다. 이름을 외부 범위에 노출시키지 않으려는 경우 쉘 기능에 특히 유용합니다.
  3. set -a # 모든 다음 할당을 내 보냅니다.

3
set -k사람이 사용할 수 있도록입니다 cmd ENVVAR=value대신 ENVVAR=value cmd하지 않는 한 예에서 작동하지 않습니다, set -k호출 이전에 실행되었다 f. 또한 요즘에는 많은 쉘이 지원하지 않으며 Bourne 쉘과의 역 호환성을 위해서만 사용됩니다. Bourne (또는 Korn) 셸에서는 기능이 작동하지 않습니다. 쉘 구문 분석에 영향을주기 때문에 쉘 이이를 사용하는 코드를 읽을 때 유효 해야합니다.
Stéphane Chazelas

1
또한 언급하고 싶을 수도 있습니다set -a
Stéphane Chazelas

24

쉘 변수와 환경 변수에는 차이가 있습니다. 쉘 변수를 지정하지 않고 정의하면, 변수 export는 프로세스 환경에 추가되지 않으므로 해당 자식에 상속되지 않습니다.

사용 export하면 쉘에 환경에 쉘 변수를 추가하도록 지시합니다. 다음을 사용하여 이것을 테스트 할 수 있습니다 printenv(환경을 인쇄 합니다. 변수 stdout는 자식 프로세스이므로 export변수 의 효과를 볼 수 있습니다 ).

#!/bin/sh

MYVAR="my cool variable"

echo "Without export:"
printenv | grep MYVAR

echo "With export:"
export MYVAR
printenv | grep MYVAR

6

한 번 내 보낸 변수는 환경의 일부입니다. PATH사용자 정의 변수는 필요에 따라 내보낼 수 있지만 쉘은 자체적으로 내보내집니다. 일부 설정 코드 사용 :

$ cat subshell.sh 
#!/usr/bin/env bash
declare | grep -e '^PATH=' -e '^foo='

비교

$ cat test.sh 
#!/usr/bin/env bash
export PATH=/bin
export foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test.sh 
PATH=/bin
foo=bar
PATH=/bin
foo=bar

$ cat test2.sh 
#!/usr/bin/env bash
PATH=/bin
foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test2.sh 
PATH=/bin
foo=bar
PATH=/bin

이후 foo쉘 내보내지지하고, test2.sh그것을 수출하지, 그것의 환경의 부분이 아니었던 subshell.sh마지막으로 실행한다.

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