Bash를 통해 하위 프로세스에 전달된 환경 제어

Bash를 통해 하위 프로세스에 전달된 환경 제어

나는 x86_64 GNU/Linux를 사용하고 있습니다.bash

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    system("set > setc");                           // A subset of `$ set`

    return 0;
}

setc 파일에 가 포함되어 있는 것을 볼 수 있습니다 $ set.
쉘(상위 프로세스)이 하위 프로세스에 제공할 것과 제공하지 않을 것을 어떻게 결정하는지 궁금합니다.
하위 프로세스에 더 많은 환경 변수를 제공하려면 어떻게 해야 합니까? 어떻게 통제할 수 있나요?

답변1

쉘 내장은 set환경으로 내보낸 변수뿐만 아니라 모든 변수를 표시합니다.

환경에 변수를 추가하려면 export variablename셸에서 실행하면 됩니다.

답변2

뒤에서 환경 변수가 한 프로그램에서 다른 프로그램으로 전송되는 방식은 다음과 같습니다.execve디스크에서 새 프로그램 이미지를 로드하는 시스템 호출입니다. (이미지가 현재 프로그램을 대체합니다. 또 다른 시스템 호출이 있습니다.fork, 현재 프로그램 기능(예: systemCombine fork) execve및 기타 시스템 호출을 복사하여 하위 프로세스를 시작합니다. ) 이 낮은 수준에서 프로그램은 원하는 모든 것을 후속 프로그램에 전달할 수 있습니다.

그러나 대부분의 프로그램은 시작 시 수신되는 환경을 단순히 전달합니다. 예를 들어 system, 프로그램의 초기 환경으로 초기화된 전역 변수를 읽는 라이브러리 함수. 예를 들어 putenv프로그램에 환경을 변경하도록 특별히 설계된 코드가 포함되어 있지 않으면 해당 환경이 하위 항목으로 전송됩니다. 프로세스.

테스트에서 쉘 명령을 사용했습니다.set. 이 명령은 환경 변수의 상위 집합인 셸 변수를 나열합니다. 셸은 모든 환경 변수를 셸 프로그래밍 언어의 변수로 표시합니다. 또한 더 많은 변수를 정의할 수 있습니다. 내장 명령export셸 변수의 이름을 인수로 사용하고 변수를 내보낸 것으로 표시합니다. 내보낸 것으로 표시된 변수는 하위 프로세스의 환경에 추가됩니다.

대화형 셸에는 일반적으로 내보내지 않은 셸 변수가 많이 있습니다. 새로 출시된 비대화형 셸의 수는 더 적습니다. 이것이 system("set")대화형 셸에서 볼 수 있는 것보다 더 적은 수의 변수를 볼 수 있는 이유입니다 . 환경 변수(명령을 사용 env하거나 인수 없이) 를 보면 export동일한 변수(또는 쉘에 따라 더 많은 변수)를 찾을 수 있습니다.

답변3

읽고 나면 man bash전체 그림이 보입니다. 질문을 게시하기 전에 그 사람의 글을 읽었더라면! 그런데 위의 답변 중 하나는 잘못된 것 같고 다른 하나는 명확하지 않습니다. 그래서:

쉘에는 호출 시 쉘이 상속하는 열린 파일, 파일 생성 모드 마스크, 환경의 쉘 부모로부터 상속된 쉘 매개변수 등으로 구성된 실행 환경이 있습니다. (자세한 내용은 " man bash명령 실행 환경" 섹션을 참조하세요.) 인수 없이 호출되면, 쉘 환경에 존재하는 모든 변수의 값(이름=값 형식)을 뱉어냅니다. (셸 환경의 출력과 구성 요소를 참고하세요.)declaresetsetdeclare

이제 내장 기능이나 쉘 기능이 아닌 간단한 명령을 실행하고 싶을 때,분리실행 환경은 쉘의 열린 파일, 파일 생성 모드 마스크, 내보내기용으로 표시된 쉘 변수 및 함수(쉘 환경의 변수 및 함수의 하위 집합) 등으로 구성됩니다. Gilles가 위의 답변에서 말했듯이 이 명령을 분기하려고 하면 "프로그램에 환경을 변경하도록 특별히 설계된 코드가 포함되어 있지 않으면 해당 환경이 하위 프로세스로 전송됩니다."

따라서 위 프로그램을 실행하려고 하면 프로그램은 셸 환경의 하위 집합을 받습니다. 그런 다음 system("set > setrc")라고 말하면 system()은 하위 프로세스(그런데 이는 쉘임)를 생성하고 하위 쉘은 를 실행합니다 set > setrc. 이를 수행할 때 프로그램은 해당 환경(상위 셸 환경의 단순화된 버전)을 하위 프로세스(셸 실행 set)로 전송합니다. 이제 set > setrc실행되면 상위 셸 환경의 단순화된 버전인 호출 셸 환경에 있는 모든 변수의 값(이름=값 형식)을 인쇄합니다. 이것이 setrc의 내용이 줄어든 이유입니다.

이제 Bash의 명령에 전달된 환경을 제어하는 ​​방법:

Bash가 명령에 전달하는 매개변수와 export함수를 제어하기 위해 및 를 사용할 수 있습니다 declare -x. ( man bash환경 섹션.)

export다른 사람들 이 언급했듯이 env명확히 하기 위해: export( env인수 없이) 쉘의 환경이 아닌 하위 프로세스(또는 명령)에 전달될 환경을 인쇄하고 set모든 declare변수를 뱉어냅니다.껍데기환경. 그렇기 때문에 $VAR_NAME(내부 set또는 출력 declare이 아니더라도 내부 env또는 출력에 존재하는 모든 변수 export)을 에코할 수 있습니다.

관련 정보