Unix에서 한 프로세스가 다른 프로세스의 환경 변수를 변경할 수있는 방법이 있습니까 (모두 동일한 사용자에 의해 실행되고 있다고 가정)? 일반적인 해결책이 가장 좋지만 그렇지 않다면 하나가 다른 하나의 자식 인 특정 경우는 어떻습니까?
편집 : gdb를 통해 어떻습니까?
Unix에서 한 프로세스가 다른 프로세스의 환경 변수를 변경할 수있는 방법이 있습니까 (모두 동일한 사용자에 의해 실행되고 있다고 가정)? 일반적인 해결책이 가장 좋지만 그렇지 않다면 하나가 다른 하나의 자식 인 특정 경우는 어떻습니까?
편집 : gdb를 통해 어떻습니까?
답변:
gdb를 통해 :
(gdb) attach process_id
(gdb) call putenv ("env_var_name=env_var_value")
(gdb) detach
이것은 매우 끔찍한 해킹이며 물론 디버깅 시나리오의 컨텍스트에서만 수행해야합니다.
ptrace: Operation not permitted
기술적으로 할 수는 있지만 (다른 답변 참조) 도움이되지 않을 수 있습니다.
대부분의 프로그램은 시작 후에 env vars를 외부에서 변경할 수 없다고 예상하므로 대부분은 시작시 관심있는 vars를 읽고이를 기반으로 초기화합니다. 따라서 나중에 변경해도 프로그램이 다시 읽지 않기 때문에 차이가 없습니다.
이것을 구체적인 문제로 게시했다면 아마도 다른 접근 방식을 취해야 할 것입니다. 호기심에서 나온 것이라면 : 좋은 질문입니다 :-).
실질적으로 아닙니다. 충분한 권한 (루트 또는 그 주변)이 있고 / dev / kmem (커널 메모리) 주위를 찌르고 프로세스의 환경을 변경했으며 프로세스가 실제로 나중에 환경 변수를 다시 참조했는지 (즉, 프로세스 이미 env var의 사본을 가져 오지 않았고 해당 사본 만 사용하지 않았습니다.) 운이 좋고 영리하고 바람이 올바른 방향으로 불고 달의 위상이 정확하다면 아마도 당신은 뭔가를 얻을 수 있습니다.
gdb
되고 변경을 수행하도록 스크립팅되며 부모 프로세스를 중단하지 않고 작동합니다. 좋습니다. 아마 할 수는 있지만 일상적으로 할 일은 아닙니다. 따라서 실질적인 목적을 위해 대답은 아니요로 유지 됩니다. 나머지 답변은 이론적으로 가능하고 다소 비현실적으로 가능한 대안을 다룹니다.
Jerry Peek 인용 :
늙은 개에게 새로운 속임수를 가르 칠 수 없습니다.
할 수있는 유일한 방법은 시작 하기 전에 자식 프로세스의 환경 변수를 변경하는 것 입니다. 죄송합니다. 부모 환경의 복사본을 가져옵니다.
자세한 내용은 http://www.unix.com.ua/orelly/unix/upt/ch06_02.htm 을 참조하십시오.
/ proc 사용에 대한 답변에 대한 의견입니다. 리눅스에서는 / proc가 지원되지만 작동하지 않으며, 루트 사용자라도 파일을 변경할 수 없습니다 . 절대적으로 읽기 전용입니다./proc/${pid}/environ
그렇게하는 다소 인위적인 방법을 생각할 수 있으며 임의의 프로세스에서는 작동하지 않습니다.
'char * getenv'를 구현하는 자체 공유 라이브러리를 작성한다고 가정합니다. 그런 다음 'LD_PRELOAD'또는 'LD_LIBRARY_PATH'환경을 설정합니다. vars를 사용하여 두 프로세스가 모두 미리로드 된 공유 라이브러리로 실행되도록합니다.
이렇게하면 기본적으로 'getenv'함수의 코드를 제어 할 수 있습니다. 그런 다음 모든 종류의 불쾌한 트릭을 할 수 있습니다. 'getenv'는 env vars의 대체 값에 대해 외부 구성 파일 또는 SHM 세그먼트를 참조 할 수 있습니다. 또는 요청 된 값에 대해 regexp 검색 / 대체를 수행 할 수 있습니다. 아니면 ...
동적 링커 (ld-linux.so)를 다시 작성하지 않고 임의의 실행 프로세스 (루트 인 경우에도)에 대해이를 수행하는 쉬운 방법을 생각할 수 없습니다.
유닉스가 / proc 파일 시스템을 지원한다면 env를 읽는 것은 쉬운 일이 아닙니다. 환경, 명령 줄, 그리고 당신이 소유 한 모든 프로세스의 다른 많은 속성을 읽을 수 있습니다. 변경 ... 글쎄, 방법을 생각할 수 있지만 나쁜 생각입니다.
좀 더 일반적인 경우 ... 모르겠습니다.하지만 휴대용 답이 있을지 의심 스럽습니다.
(편집 됨 : 내 원래 대답은 OP가 환경을 변경하지 않고 읽기를 원한다고 가정했습니다)
직접적인 대답은 아니지만 ... Raymond Chen은이 문제에 대해 [Windows 기반] 근거를 가지고있었습니다 .
... 확실히 지원되지 않는 방법이나 디버거의 도움으로 작동하는 방법이 있지만, 다른 프로세스의 명령 줄에 대한 프로그래밍 방식 액세스를 지원하는 방법은 없습니다. 최소한 커널에서 제공하는 것은 없습니다. ...
필요하지 않은 정보를 추적하지 않는 원칙의 결과는 없습니다. 커널은 다른 프로세스의 명령 줄을 얻을 필요가 없습니다.
CreateProcess
함수에 전달 된 명령 줄GetCommandLine
을 가져 와서 함수가 검색 할 수 있는 위치에서 시작되는 프로세스의 주소 공간에 복사 합니다. 프로세스가 자체 명령 줄에 액세스 할 수있게되면 커널의 책임이 수행됩니다.명령 줄이 프로세스의 주소 공간에 복사되기 때문에 프로세스는 명령 줄이있는 메모리에 쓰고 수정할 수도 있습니다. 이런 일이 발생하면 원래 명령 줄이 영원히 손실됩니다. 알려진 유일한 사본이 덮어 써졌습니다.
즉, 그러한 커널 기능은
그러나 가장 가능성이 높은 이유는 단순히 그러한 시설에 대한 사용 사례가 제한되어 있기 때문입니다.
보인다 하는 putenv가 지금은 작동하지 않지만 에서는 setenv는 않습니다. 나는 성공하지 못한 현재 쉘에서 변수를 설정하려고 시도하면서 받아 들여지는 대답을 테스트하고 있었다.
$] sudo gdb -p $$
(gdb) call putenv("TEST=1234")
$1 = 0
(gdb) call (char*) getenv("TEST")
$2 = 0x0
(gdb) detach
(gdb) quit
$] echo "TEST=$TEST"
TEST=
작동 방식 :
$] sudo gdb -p $$
(gdb) call (int) setenv("TEST", "1234", 1)
$1 = 0
(gdb) call (char*) getenv("TEST")
$2 = 0x55f19ff5edc0 "1234"
(gdb) detach
(gdb) quit
$] echo "TEST=$TEST"
TEST=1234