Bash를 사용하는 대부분의 *nix 환경에서는 환경 변수 ~/.bash_profile
또는 사용자 로컬의 유사한 파일을 변경한 다음 source
변경 사항이 세션에 적용되도록 변경된 파일을 변경합니다.
마찬가지로, 변경 후 source
ing을 실행하면 /etc/profile
해당 변경 사항이 현재 세션에 적용됩니다.
/etc/profile
그러나 (또는 그 아래 어딘가에 ) 정의 된 /etc/profile.d/
환경 변수를 변경해야 하고 시스템에 있는 모든 사용자의 모든 세션에서 변경 사항이 즉시 표시되기를 원한다고 가정해 보겠습니다. 시스템을 재부팅하지 않고 이를 달성하려면 어떻게 해야 합니까?
답변1
로그인한 모든 사용자를 강제로 로그오프하고 다시 로그인하도록 할 수 있습니다(그리고 /etc/profile을 사용하여 셸에서 시작한 모든 데몬을 종료하고 다시 시작합니다). 재부팅이 필요하지 않습니다.
그 외에는 할 수 없습니다.
source /etc/profile
당신이 할 수 있는 일은 새로운 정의가 필요한 각 쉘 세션에서 별도로 /etc/profile을 가져오는 것뿐입니다... 그러나 이것은 실제로 실행 하거나 사용할 수 있는 쉘에만 영향을 미칩니다 . /etc/profile
. 예를 들어 환경 A와 같이 기존 쉘을 직접 변경할 수는 없습니다. 이미 실행 중인 프로세스(예: 실행 중인 X 세션)
하위 프로세스할 수 없다상위 프로세스의 환경을 변경합니다. 어쨌든 직접적이지는 않습니다(부모 프로세스할 수 있다자신의 환경을 변경하는 것을 포함하여 자식이 수행하는 작업을 관찰하고 이에 따라 행동합니다. 하지만 이는 완전히 다른 것이며 부모 프로세스에 프로그래밍해야 합니다.)
답변2
실제로는 그럴 필요가 없습니다.
그 이유는 환경 변수가 실행 시(명령줄 인수와 동일한 방식으로) 프로그램에 전달되지만 이후에는 프로세스 메모리 어딘가에 있는 테이블일 뿐이기 때문입니다. 일반적으로 외부 또는 다른 프로세스에서 수정할 수 없습니다.당신은 그 사람들이 어디에 있는지 몰라요.
environ
C 라이브러리는 집합적으로 "환경"이라고 불리는 값을 가리키는 포인터 목록을 가리키는 포인터라는 이름을 유지합니다 . 프로그램 수명 동안 테이블의 위치를 재할당해야 하는 경우 테이블의 위치가 변경될 수 있으며 값의 위치도 유사하게 변경됩니다.
포인터 자체는 프로그램이 실행되는 동안 같은 위치에 있기 environ
때문에 포인터를 찾는 한 합리적으로 값을 해킹할 수 있습니다. 주소 공간 레이아웃 무작위화와 같은 작업으로 인해 다른 프로그램 호출에서 다른 위치에 있을 수 있습니다. 이를 찾아 프로그램의 메모리를 변경하더라도 프로그램이 값(또는 해당 포인터)을 다른 곳에 복사하여 사용했는지 알 수 없습니다. 유사한 구성 파일의 내용이 프로그램 메모리의 한 위치에 복사됩니다.
execve()
시스템 호출 수준에서는 환경 값이 시스템 호출에 대한 인수로 명시적으로 전달되어야 하고 거기에 전달된 테이블이 무엇과 어떤 관계를 가질 필요가 없기 때문에 프로그램 실행 중에 환경이 자동으로 복사되지도 않습니다. 실행 프로세스에서는 이를 호출합니다 environ
.
이 모든 것은 또한 Linux에 표시되는 내용이 /proc/$pid/environ
프로그램의 시스템 호출에 의해 반환되는 내용과 일치하지 않을 수 있음을 의미합니다. getenv()
(파일에는 프로그램이 실행되는 동안 값을 전달하는 데 사용되는 메모리 영역이 표시되어 있는 것 같습니다.) "환경"이 어떤 특수한 데이터 구조라는 발상은 완전히 옳지 않습니다.
실행 중인 프로그램의 구성을 수정하려면 프로그램 자체의 지원이 필요하며, 프로그램은 어딘가에서 구성을 다시 로드할 수 있어야 합니다. 아니면 최소한 부모로부터 다시 로드를 지원받거나그것은구성한 다음 하위 프로세스를 다시 시작하여 다른 환경 변수 세트를 전달합니다.