python에서 os의 environ이 무엇을 담고 있는지 간단하게 알아보겠습니다.

 


 먼저, cho로 로그인 한 쉘입니다. 변수 CHO의 값을 출력해 보니 3이 나왔습니다.

 

 

 다음에 root 쉘로 로그인 했습니다. 마찬가지로 쉘 변수 CHO를 출력해 보니, 10이 나왔습니다. 여기서 중요한 것은 cho로 로그인이 된 쉘의 CHO와 root 쉘의 CHO의 값이 달랐다는 점입니다. 이제, os의 environ으로부터 변수 'GH'의 값을 얻어봅시다. 1.py에, 그러한 일을 수행하는 코드를 작성하였습니다.

 

 

 단 두 줄이면 얻어낼 수 있습니다. 이 코드는 'GH'의 값을 얻어냅니다.

 

 

 cho로 로그인 한 쉘에서는 3을 출력합니다.

 

 

 그런데, root로 로그인 한 쉘에서는 10을 출력합니다. 이를 토대로 추측할 수 있는 것은, 프로세스의 환경과 관련된 무언가를 나타내는 것이 os.environ이라고 할 수 있어요. 그리고 문서에 언급이 된 부분은, os.environ은 처음에 os 모듈이 로딩될 때 캡쳐가 된다는 것입니다. 이 말이 무슨 이야기일까요?

 


 이런 상황을 생각해 봅시다. 환경 변수 'g'의 값이 5였습니다. 파이썬 프로그램을 실행했습니다. os module을 import 한 다음에, os의 environ에 있는 'g' 값을 출력합니다. 다음에, 쉘 변수 'g'를 5로 바꿨습니다. 그 이후에 제가 실행시킨 파이썬 프로세스의 environ의 'g'값은 어떻게 될까요? 5가 될까요? 3이 될까요?

 

 제 우분투 환경에서 테스트 해 보겠습니다. 처음 'GH'의 값은 3이였고, 중간에 'GH'를 5로 바꾸겠습니다.

 

 2.py입니다. 처음에 환경 변수 'GH'를 출력하고 난 후 10초 후에 다시 'GH'의 값을 출력합니다. 이 프로그램을 백그라운드로 실행시킬 거에요. 그리고, 리다이렉션을 통해서 어떤 값이 출력되는지 볼 거에요.

 

 

  2.py의 output을 모두 out.txt로 보내고, background로 실행합니다.

 

 

 3, 3이 출력됩니다. 이 말인 즉슨, 캡쳐가 된 후에는 제가 프로그램 안에서, 직접 os.environ['GH'] = 5로 설정하지 않는 이상 변하진 않는다는 소리입니다.

 

 


 문서의 이 부분을 보면, environment를 바꾼 경우, subprocess가 시작할 때, 변경이 적용 된다고 되어 있는데요. 이건 또 무슨 말일까요? 실험을 하나 해 봅시다.

 

 저는 부모 프로세스에서, 'MAL'이라는 환경 변수의 값을 'TISE'라고 설정했어요. 자식 프로세스에서 'MAL' 환경변수의 값을 출력하려고 합니다. 어떤 값이 출력될까요?

 

 

 TISE가 잘 출력되었음을 볼 수 있습니다. 'MAL'이 적용되고 나서, fork가 호출되었는데, 이 때 자식 프로세스가 시작한 시점과 동일해요. 중요한 것은 부모 프로세스의 'MAL'의 값과 자식 프로세스의 'MAL' 값이 같았다는 것입니다. 결국, 부모 프로세스의 환경 변수들의 변경점이, 추후에 자식 프로세스를 생성할 때 반영이 되었다는 의미입니다.

 

 django에서 app config를 1번만 호출하려고 할 때 아래 로직을 썼었습니다.

 

 no reloader 옵션이 없다면, 부모를 띄우고, 자식인 reloader를 띄우게 되는데요. 부모를 띄우는 시점에 'APP'이라는 환경 변수를 'True'라고 설정해 놓습니다. 이것이 설정된 후에 자식인 reloader가 띄워지게 되는데, 이미 부모가 'APP' 이라는 환경 변수를 셋팅해 놓았기 때문에, 자식 프로세스를 생성할 때 반영이 됩니다. 그리고, 자식 프로세스가 ready를 부를 때는 이미, 'APP'이라는 변수가 있기 때문에, 10번째 줄의 if문 안쪽에 있는 블록들을 타지 않습니다.