프로세스가 상위 프로세스의 환경을 상속하는 경우 이를 내보내야 하는 이유는 무엇입니까?

프로세스가 상위 프로세스의 환경을 상속하는 경우 이를 내보내야 하는 이유는 무엇입니까?

나는 읽었다여기셸의 목적 export은 셸에서 시작된 하위 프로세스에 변수를 사용할 수 있도록 하는 것입니다.

그러나 나는 또한 읽었습니다.여기그리고여기저것"프로세스는 상위(프로세스를 시작한 프로세스)로부터 환경을 상속받습니다."

그렇다면 왜 필요한가요 export? 내가 무엇을 놓치고 있나요?

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

답변1

귀하의 가정은 쉘 변수가환경에서. 이것은 정확하지 않습니다. 이 export명령은 환경의 이름을 정의합니다. 그러므로:

a=1 b=2
export b

최신 결과입니다껍데기$a1과 2로 확장될 것이라는 것을 알고 있지만 하위 프로세스는 환경의 일부가 아니기 때문에(현재 셸에서도) $b아무것도 알지 못합니다 .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# 다음 각 작업을 내보냅니다.

동기 부여

그렇다면 쉘에는 왜 자체적인 다른 변수와 환경이 필요한가요? 물론 몇 가지 역사적인 이유가 있을 거라 확신하지만, 주된 이유는 범위 지정 때문이라고 생각합니다. 이 환경은 하위 프로세스용이지만 하위 프로세스를 포크하지 않고도 셸에서 많은 작업을 수행할 수 있습니다. 루프를 반복한다고 가정해 보세요.

for i in {0..50}; do
    somecommand
done

somecommand을 포함하여 i환경을 필요한 것보다 더 크게 만들어 메모리를 낭비하는 이유는 무엇입니까? 쉘에서 선택한 변수 이름이 프로그램이 의도하지 않은 것을 의미한다면 어떻게 될까요? (제가 개인적으로 가장 좋아하는 이름에는 DEBUG. 및 가 있습니다 VERBOSE. 이러한 이름은 어디에나 있지만 네임스페이스가 거의 없습니다.)

쉘이 아니라면 어떤 환경인가요?

때로는 Unix 동작을 이해하기 위해 커널 및 운영 체제와 상호 작용하기 위한 기본 API인 시스템 호출을 살펴봐야 합니다. 여기서는 exec하위 프로세스를 생성할 때 쉘에서 사용되는 호출 시리즈를 살펴보겠습니다 . 이것은에서 온 것입니다맨페이지exec(3)(강조):

execle()함수를 사용하면 execvpe()호출자가 envp 매개변수를 통해 프로그램이 실행되는 환경을 지정할 수 있습니다. envp 매개변수는 NULL로 끝나는 문자열에 대한 포인터 배열이며 NULL 포인터로 끝나야 합니다.다른 함수는 호출 프로세스의 외부 변수environ에서 새 프로세스 이미지의 환경을 가져옵니다.

따라서 셸에 쓰는 것은 C의 전역 사전 export somename에 이름을 복사하는 것과 같습니다 . environ그러나 somename내보내지 않고 할당하는 것은 C에서 변수에 복사하지 않고 할당하는 것과 같습니다 environ.

답변2

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

export환경에 추가하도록 쉘에 지시한 쉘 변수를 사용하십시오 . 다음을 사용하여 테스트할 수 있습니다. printenv(환경을 에 인쇄하고 stdout하위 프로세스이므로 exporting 변수의 효과를 볼 수 있습니다.)

#!/bin/sh

MYVAR="my cool variable"

echo "Without export:"
printenv | grep MYVAR

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

답변3

변수를 내보내면 해당 변수는 환경의 일부가 됩니다. 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

답변4

간단히 말해서:

  • 프로세스는 상위 프로세스로부터 환경 변수를 상속받습니다.
  • Bash에서 $a=1은 환경 변수가 아닌 "일반" 변수를 생성합니다.
  • 내보내기 a=1은 터미널 프로세스에 대한 환경 변수를 생성합니다(다른 방법이 있음)
  • 환경 데이터를 하위 프로세스에 전달하는 다른 방법이 있습니까?

관련 정보