나는 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
, 현재 프로그램 기능(예: system
Combine fork
) execve
및 기타 시스템 호출을 복사하여 하위 프로세스를 시작합니다. ) 이 낮은 수준에서 프로그램은 원하는 모든 것을 후속 프로그램에 전달할 수 있습니다.
그러나 대부분의 프로그램은 시작 시 수신되는 환경을 단순히 전달합니다. 예를 들어 system
, 프로그램의 초기 환경으로 초기화된 전역 변수를 읽는 라이브러리 함수. 예를 들어 putenv
프로그램에 환경을 변경하도록 특별히 설계된 코드가 포함되어 있지 않으면 해당 환경이 하위 항목으로 전송됩니다. 프로세스.
테스트에서 쉘 명령을 사용했습니다.set
. 이 명령은 환경 변수의 상위 집합인 셸 변수를 나열합니다. 셸은 모든 환경 변수를 셸 프로그래밍 언어의 변수로 표시합니다. 또한 더 많은 변수를 정의할 수 있습니다. 내장 명령export
셸 변수의 이름을 인수로 사용하고 변수를 내보낸 것으로 표시합니다. 내보낸 것으로 표시된 변수는 하위 프로세스의 환경에 추가됩니다.
대화형 셸에는 일반적으로 내보내지 않은 셸 변수가 많이 있습니다. 새로 출시된 비대화형 셸의 수는 더 적습니다. 이것이 system("set")
대화형 셸에서 볼 수 있는 것보다 더 적은 수의 변수를 볼 수 있는 이유입니다 . 환경 변수(명령을 사용 env
하거나 인수 없이) 를 보면 export
동일한 변수(또는 쉘에 따라 더 많은 변수)를 찾을 수 있습니다.
답변3
읽고 나면 man bash
전체 그림이 보입니다. 질문을 게시하기 전에 그 사람의 글을 읽었더라면! 그런데 위의 답변 중 하나는 잘못된 것 같고 다른 하나는 명확하지 않습니다. 그래서:
쉘에는 호출 시 쉘이 상속하는 열린 파일, 파일 생성 모드 마스크, 환경의 쉘 부모로부터 상속된 쉘 매개변수 등으로 구성된 실행 환경이 있습니다. (자세한 내용은 " man bash
명령 실행 환경" 섹션을 참조하세요.) 인수 없이 호출되면, 쉘 환경에 존재하는 모든 변수의 값(이름=값 형식)을 뱉어냅니다. (셸 환경의 출력과 구성 요소를 참고하세요.)declare
set
set
declare
이제 내장 기능이나 쉘 기능이 아닌 간단한 명령을 실행하고 싶을 때,분리실행 환경은 쉘의 열린 파일, 파일 생성 모드 마스크, 내보내기용으로 표시된 쉘 변수 및 함수(쉘 환경의 변수 및 함수의 하위 집합) 등으로 구성됩니다. 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
)을 에코할 수 있습니다.