2011-10-05 4 views
8

선생님을 해석하는 데 많은 어려움을 겪고 있습니다. 우리는 당신이 할 수있는 그런 식으로 내 보낸 변수로에게 환경 당신에게 설치를 보내고/빈/bash는의 서브 쉘을 산란하는 내장 명령을 생성, 해명을 요구하고, 다시 그에게서execve 및 환경 변수 요구 사항을 이해

  1. 를 원하면 execve 다음 있어요 env를 사용하여 내 보낸 변수를 확인하십시오.

    (그는 여기에 우리의 자신의 환경을 만드는 방법에 대해 바르 얘기입니다.)

  2. 네 자신을 만들 수 있습니다. 쉘이 시작될 때 environ을 복사하여 시작하고 내 보낸 변수 만 추가 할 수 있습니다.

이 항목은 나를 통해 스택 오버플로에 관한 다음 게시물과 관련이 있습니다 (이 다른 게시물을 읽으면 내가하는 일을 이해하는 데 도움이됩니다).

using a new path with execve to run ls command

우리는 이것에 대해 매우 혼란이다. 한 번 더 우리가 지금하려고하는 것을 설명 할 것입니다. 리눅스 쉘이 이와 비슷하게 PATH와 USER와 같은 환경 변수를 설정할 수있는 프로그램을 작성해야하며, 사용자가 정의하고자하는 다른 변수를 정의 할 수 있어야합니다.

이은 (는 프롬프트에서 프로그램 내에서) 될 것 부를 것이다 방법의 예 :

mysetenv dog spike 

더 중요한 것은 "개 = 스파이크"

처럼 보이는 환경 변수를 만들 것이다, 우리는 우리 자신의 PATH 변수를 설정하고 exec 명령으로 보낼 수 있어야합니다. 이것은 모든 질문에 기초하여 우리가해야 할 일을 이해하지 못하기 때문에 혼란스러운 부분입니다.

답변

26

실제로는 매우 간단합니다. 인수가 NULL 포인터로 종료 된 char *의 목록임을 이미 알고 있습니다. 비슷하게, 환경은 NULL 포인터로 끝나는 char *의 목록 일뿐입니다. 일반적으로 목록의 값은 VARNAME=var-value의 형식을 취하지 만 원하는 경우 다른 형식을 전달할 수 있습니다.

그래서, 간단한 경우를 취할 :이 예에서

#include <unistd.h> 
#include <stdio.h> 

int main(void) 
{ 
    char *argv[] = { "/bin/sh", "-c", "env", 0 }; 
    char *envp[] = 
    { 
     "HOME=/", 
     "PATH=/bin:/usr/bin", 
     "TZ=UTC0", 
     "USER=beelzebub", 
     "LOGNAME=tarzan", 
     0 
    }; 
    execve(argv[0], &argv[0], envp); 
    fprintf(stderr, "Oops!\n"); 
    return -1; 
} 

, 프로그램이 쉘은 현재 PATH에있는 env 프로그램을 실행 즉, 인수 -cenv/bin/sh를 실행합니다. 여기 환경은 정통 형식의 5 가지 값을 포함하도록 설정됩니다. envdate (또는 env; date)으로 변경하면 예를 들어 TZ 설정의 효과가 표시됩니다. 내 맥 OS X 시스템에서 그것을 실행하면 출력은 다음과 같습니다

USER=beelzebub 
PATH=/bin:/usr/bin 
PWD=/Users/jleffler/tmp/soq 
TZ=UTC0 
SHLVL=1 
HOME=/ 
LOGNAME=tarzan 
_=/usr/bin/env 

쉘 내가 execve() 호출에 명시 적으로 설정하는 사람에 환경 변수 SHLVL, _PWD을 추가했다.

또한 명시 적으로 설정하려는 환경 변수와 충돌하지 않는 실제 환경의 다른 환경 변수에서 복사하는 등의 더 멋진 작업을 수행 할 수 있습니다.환경에서 하나의 변수에 대해 두 개의 값을 갖는 것과 같은 게임을 할 수도 있습니다. 그리고 공백이 포함 된 변수 이름 (셸이 그다지 좋아하지 않는) 또는 'varname = value'표기법 (등호 없음)과 일치하지 않는 항목으로 게임을 할 수 있습니다.

+0

당신은 저를 위해 모든 것을 정말로 정리했습니다. 나는 이미 모든 것을 바꿨지만, 고마워! 이제 이해가된다. – james

1

PWD (작업 디렉토리) 변수를 변경하려는 경우를 제외하고 의 코드는 Jonathan Leffler입니다.

내가 무슨 짓을, 작업 디렉토리를 변경하기 위해, execve(..) 전에 chdir(..)을 넣고 전화를했다 :

chdir("/foo/bar"); 
execve(argv[0], &argv[0], envp); 
0

을 여기 늦게 파티에 조금 해요,하지만 당신은 유지하려는 경우 이전 환경 변수뿐만 아니라 자신 만의 환경 변수를 생성하려면 setenv을 사용하고 environexecve()으로 전달하십시오.

setenv("dog", "spike", 1); 
    extern char** environ; 
    execve(argv[0], argv, environ); 

environ

unistd.h 선언은 변수이며,이 주행 과정에서의 환경 변수의 트랙을 유지한다.

setenv()putenv() 수정 environ이므로 execve() 이상으로 전달하면 예상대로 환경 변수가 전달됩니다.