C언어로 환경변수를 설정하려면???

yundorri의 이미지

안녕하세요, 완연한 겨울입니다.
지구온난화로 올겨울이 짧다고는 하지만 그래도 겨울은 겨울, 모두들 건강하시고...

C 코드로 환경변수를 설정하고싶습니다.
컴파일된 프로그램을 실행하고 나서 echo로 확인해봤을 때 설정되어있도록 할 수있을까요?

  1 #include <stdlib.h>
  2 #include <stdio.h>
  3 #include <unistd.h>
  4 #include <string.h>
  5
  6 #define __INFRA_VERSION__    "3.0"
  7
  8 int main()
  9 {
 10     int result = setenv( "INFRA_VER", __INFRA_VERSION__, 1 );
 11     if( result == 0)
 12     {
 13         printf( "set env ok\n" );
 14         int result = putenv( "INFRA_VER" );
 15         if( result == 0) printf( "put env ok\n" );
 16         else printf( "put env failure\n" );
 17     }
 18     else printf( "set env failure\n" );
 19
 20     printf( "$HOSTNAME= \"%s\"\n", getenv( "HOSTNAME" ) );
 21     printf( "$INFRA_VER= \"%s\"\n", getenv( "INFRA_VER" ) );
 22
 23     system( "INFRA_VER=3.0" );
 24     system( "export INFRA_VER" );
 25     printf( "$HOSTNAME= \"%s\"\n", getenv( "HOSTNAME" ) );
 26     printf( "$INFRA_VER= \"%s\"\n", getenv( "INFRA_VER" ) );
 27
 28     return 0;
 29 }

위와 같이 하였을 때 이미 설정되어있는 HOSTNAME은 잘 출력됩니다만 INFRA_VER는 출력이 되지 않습니다.

[yundorri@swdev2 main]$ ./main
set env ok
put env ok
$HOSTNAME= "swdev2"
$INFRA_VER= "(null)"
$HOSTNAME= "swdev2"
$INFRA_VER= "(null)"
[yundorri@swdev2 main]$ 

어떻게 해야될까요? 고수님들의 조언 부탁드립니다.

Hyun의 이미지

main 프로그램을 실행할 때 bash가 fork 를 해서 main을 실행하기 때문에 자식 프로세스인 main 에서 부모의 환경변수를 바꾸는건 불가능할 것 같습니다.

혹 스크립트에서 현재 환경변수를 수정하려면 스크립트를 다음과 같이 만든 후 a 파일에 저항 하고

export INFRA_VER=abcd

$ . a

처럼 . 명령을 이용해 현재 쉘에서 바로 스크립트를 실행하면 현재 쉘의 환경변수를 수정할 수 있습니다.
7339989b62a014c4ce6e31b3540bc7b5f06455024f22753f6235c935e8e5의 이미지

비슷한 내용의 글타래인데요. 안된다는 것 같네요;
http://kldp.org/node/20487

yundorri의 이미지

안되나 보군요.
파일로 작성하여 파일을 읽어서 버전을 알아내도록 바꿔야 겠네요. 흑~
답변주신분들 감사드립니다.

근데, 그렇다면 setenv(), getenv(), putenv()는 도데체 어떨 때 쓰이는 함수들인가요?

auditory의 이미지

새로 shell을 만들어서 그 안에서 환경변수를 바꾼것이니

main을 실행하는 동안은 setenv로 설정된 변수가 유지되지 않나요?

setenv("TEST","ABC",1);
printf("%s\n", getenv("TEST"));

는 잘 동작합니다
원글의 예에서는

int result = putenv( "INFRA_VER" );

에서 INFRA_VER에 설정된걸 다시 날려버리는 결과가 나온것 같습니다.

setenv( "INFRA_VER", __INFRA_VERSION__, 1 );

또는
putenv("INFRA_VER="__INFRA_VERSION__ );

둘중에 하나만 하면 되는거 아닌가요?

물론 이렇게 해도 프로그램이 끝나고
echo로 출력하면 당연히 안나오겠죠.. shell이 바뀌었으니..

getenv/setenv의 용도에 대한 답변인 셈이네요..

cinsk의 이미지

한 프로세스의 환경 변수를 변경하면 자기 자신의 환경 변수에 영향을 줍니다.
또는 그 프로세스의 자식 프로세스에게도 영향을 줄 수 있도록 할 수 있습니다. (export 명령)

그러나, 자신과 관련 없는 프로세스나, 자신의 부모 프로세스의 환경 변수에 영향을 줄 수 있는 방법은 존재하지 않습니다.

따라서, 질문하신 프로그램은, 그 프로그램이 실행하고 있을 동안에 환경 변수에는 영향을 주지만, 그 프로그램이 끝나면, 부모 프로세스인 shell로 복귀하기 때문에, 이 shell에서 환경 변수의 내용을 살펴보더라도 변경된 것을 확인할 수가 없습니다.

비슷한 이유로, C 프로그램을 작성해서, parent shell의 현재 디렉토리를 바꾸는 것도 불가능합니다.

꼭 현재 shell의 환경 변수를 바꿔야겠다면, shell의 source 명령을 쓰거나, wrapper script를 만들어서 그 안에서 위 프로그램을 실행해서 바꾸는 방법이 있습니다.

예를 들어, 프로그램이 특정 정보를 파일에 기록하고, wrapper script가 이 프로그램을 호출한 다음, 그 파일의 내용을 읽어서 특정 정보를 설정하도록 할 수 있습니다. 또는 프로그램 자체가 shell 문법에 맞는 내용을 출력하도록 하고, wrapper script가 그 내용을 받아서 eval 명령으로 실행하는 방법도 있습니다. 전자의 경우, mc package에 따라오는 mc-wrapper.sh란 파일을 참고하기 바랍니다.

--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/

semmal의 이미지

정확히 원하시는게 뭔지 모르겠네요.

#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;string.h&gt;
#define __INFRA_VERSION__    "3.0"
int main()
{
    setenv( "INFRA_VER", __INFRA_VERSION__, 1 );
    printf( "$INFRA_VER= \"%s\"\n", getenv( "INFRA_VER" ) );
    system( "INFRA_VER2=3.0;export INFRA_VER2" );
    printf( "$INFRA_VER2= \"%s\"\n", getenv( "INFRA_VER2" ) );
    return 0;
}

이 결과는

semmal@semmal:~/workspace/env$ ./env
$INFRA_VER= "3.0"
$INFRA_VER2= "(null)"

이 처럼 나옵니다.
system 함수의 경우에는 쉘을 통해서 실행되므로 INFRA_VER2는 바뀌지 않지만, setenv를 통해서는 바뀌었습니다.

------------------------------
How many legs does a dog have?

------------------------------
How many legs does a dog have?

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.