노무현 대통령 배너


2006. 6. 2. 14:42

환경변수(environment variable)

"환경변수(environment variable)"란 어떤 프로그램 하나가 아니라, linux OS 환경에서 사용되는 변수를 말합니다. linux OS 환경 전체에 대한 전역변수라고 생각하시면 됩니다.그러므로모든 프로그램에서 읽고 쓸 수가 있습니다.

linux 명령어 라인에서 ps라고 입력하게 되면다음과 같은 결과를 볼 수가 있습니다.

# ps
PID TTY TIME CMD
12131 pts/0 00:00:00
bash
12170 pts/0 00:00:00 ps

그 중 첫번째 내용 끝부분에 가보면bash라는 단어가있습니다. 이것이 내가 현재 쓰고 있는 shell의 이름입니다.Shell에는 sh, ksh, csh, zsh, bash 등이 있습니다.

setenv라는 명령어는 csh라고 하는 C-Shell에서 사용됩니다. setenv는 bash, sh 등에서 사용되지 않는 내부 명령어입니다.

# setenv ROOT /usr/local

이 명령어는 ROOT라는 변수에 "/usr/local"를 넣겠다는 뜻입니다.Unix에서 변수의 사용은 "$변수명"으로 사용합니다.

그러므로

# setenv GPROOT $ROOT/aic-export 는 GPROOT라는 변수에 /usr/local/aic-export 를넣는다는 뜻입니다.

Linux에서 setenv는사용되지않습니다. setenv라는 명령어는 위에서 말한바와 같이 변수를 설정하는 명령어 입니다. 변수 설정 명령어는 현재 사용중인 Shell에 따라 조금씩 차이가 있습니다.

그외 sh, ksh, bash에서는 export라는 명령어를 사용하게 됩니다. bash 에서는 아래와같이 지정합니다.

# export PATH="/bin:/usr/bin:/opt/app/bin"

csh과 다르게 '=' 을 변수명과 값 사이에 넣어주어야 합니다. 지정 한후에 제대로 되어 있는지 확인하려면 아래와 같이 알아 볼 수 있습니다.

# echo $PATH

환경 변수는 셀 프로그램에서 많이 사용합니다. 일반 프로그램의 변수와 똑같다고 생각하면 됩니다. 예를 들러 1+2=3 이다. 이때 답3 을 환경 변수에 넣고 (export d=3) echo $d 하면 3이 나옵니다.

환경 변수는 실행 프로그램들에 운영체제의 환경과 실행 프로그램의 환경을 알려주기 위해서 주로 사용됩니다. 이러한 환경변수는 shell에서 set 명령을 이용해서 확인 가능합니다.

$ set
HOME=/home/yundream
BASH=/bin/bash
LANG=en_US
TERM=xterm-color
LD_LIBRARY_PATH=/usr/local/lib:/usr/local/mysql/lib
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
....

위의 환경변수들이 세팅되어 있기 때문에, 해당 프로그램들은 현재 사용자가 어떤 터미널을 사용하는지, 어떤 언어 환경인지, 실행 프로그램을 찾기 위해서 어떤 디렉토리를 검색해야 하는지를 알수 있게됩니다. 이러한 환경변수의 조작은 setenv(3), getenv(3), putenv(3) 를 통해서 이루어집니다.


#include
#include
#include
#include

#define LOG_FILE_NAME "my.dump"


int main(int argc, char **argv)
{
char *tmp_dir;
char log_file[30];
char *my_env;

int fd;
if ((tmp_dir = getenv("TMP_DIR")) == NULL)
{
printf("TMP_DIR 이 세팅되어 있지 않습니다n"
"TMP_DIR 를 먼저 세팅하셔야 합니다n");
exit(0);
}

memset(log_file, '', 30);
sprintf(log_file, "%s/%s", tmp_dir, LOG_FILE_NAME);
printf("log_file is %sn", log_file);

printf("your home directory is %sn", getenv("HOME"));

my_env = (char *)malloc(40);
memset(my_env, '0', 40);

sprintf(my_env, "%s=%s", "USER_ENV", "hello yundream");

putenv("TEST_ENV=hello world");
putenv(my_env);
printf("여기에서 부터는 execln");

execl("/bin/sh","sh",0);
}

위의 프로그램을 컴파일 해서 실행시켜 봅니다. 처음에 실행시키면, TMP_DIR 환경 변수를 검사해서 이 값이 세팅되어 있지 않으면 에러 메시지를 보내고 프로그램이 종료되도록 되어 있습니다. 그러므로 먼저 TMP_DIR을 세팅해 주어야 합니다.


bash 쉘이라면
$ export TMP_DIR="/tmp"

csh 쉘이라면
$ setenv TMP_DIR="/tmp"

로 설정할수 있습니다. 환경변수 TMP_DIR 의 설정을 마치고 프로그램을 실행하면, setenv 를 통해서 환경변수 TMP_DIR 의 내용과 HOME 의 내용을 제대로 가져옴을 볼수 있을것이다.

그리고 putenv() 를 이용해서 새로운 환경변수를 설정했습니다. putenv의 사용법은 쉘에서 처럼 변수명=값 의 형식으로 설정하면됩니다. 주의 할점은 putenv() 에 값을 입력할때, char * 형일 경우 반드시 메모리 할당을 한 값을 입력해야 한다는 점입니다.putenv 를 마치고 나면 execl 함수를 이용해서 새로 쉘을 띄웁니다. 새로 뜬 쉘에서 echo $USER_ENV, echo $TEST_ENV 명령을 사용해 보면 putenv 를 통한 환경 설정이 제대로 적용 되었음을 알수 있을 것입니다. 그러나 exit 를 통해서 원래 쉘로 되돌아온 다음에 echo 를 이용해보면 USER_ENV, TEST_ENV 의 값이 출력되지 않음을 보게 될것입니다.
putenv 와 setenv 를 통해서 설정된 환경변수는 현재 프로그램과 그 프로그램에서 파생된(fork 혹은 exel 된) 프로그램에만 적용되기 때문입니다.


환경변수를 제대로 사용하면 프로그램의 작성이 매우 간편해짐을 알수 있습니다. 매번 복잡하게 프로그램의 인수로 프로그램을 작동시키는데 필요한 각종 설정을 입력할 필요도 없고, 프로그래밍 하기 곤란한 설정 파일을 파싱하는 루틴을 만들 필요도 없기 때문입니다.


단점은 프로그램의 사용자에게 사용상의 혼란을 줄수가 있다는 점과, 환경 변수의 특성상, 해당 환경 변수를 100% 신뢰 할수 없다라는 문제가 그것입니다. 물론 전자의 경우는 사용자에게 메뉴얼을 숙지할 수 있도록 해주면 되고(오라클을 설치할 경우도 우리는 오라클 설치에 필요한 많은 환경 설정을 위해서 메뉴얼을 숙지해야 한다). 후자의 경우도 이론상 100% 신뢰할 수 없다라는 것이고, 약간만 주의를 기울인다면 문제 발생의 여지는 거의 없다고 할수 있습니다.


환경 변수는 프로세스의 스택 영역에 저장돼고, putenv(), getenv()는 스택영영에 대한 사용자 레벨에서의 제어를 가능하도록 도와줍니다. 이외에도 좀더 낮은 수준에서 환경 변수를 읽어 올 수 있는데, main()함수의 3번째 인자를 이용하는 방법입니다. main()함수의 3번째 인자는 환경 변수가 저장된 주소를 가르키며, 우리는 이 포인터를 이용해서 환경 변수를 얻어올 수 있습니다. 다음은 간단한 예제 코드입니다.


#include
#include

int main(int argc, char **argv, char **env)
{
while(*env)
{
printf("%sn", *env);
env++;
}
}

위의 프로그램을 실행시키면 다음과 같은 결과를 출력할 것입니다. 결과는 물론 시스템에 따라서 달라질 수 있습니다.

[root@yundream test]# ./env
SSH_AGENT_PID=997
KDE_MULTIHEAD=false
HOSTNAME=yundream
TERM=xterm
SHELL=/bin/bash
DESKTOP_STARTUP_ID=yundream;1079054007;831298;1040
HISTSIZE=1000
GTK2_RC_FILES=/etc/gtk-2.0/gtkrc:/root/.gtkrc-2.0:/root/.kde/share/config/gtkrc
GS_LIB=/root/.fonts
GTK_RC_FILES=/etc/gtk/gtkrc:/root/.gtkrc:/root/.kde/share/config/gtkrc
WINDOWID=62914580
OLDPWD=/root
QTDIR=/usr/lib/qt-3.2
KDE_FULL_SESSION=true
USER=root
....

아래의 두 라인은 같다.

# export PATH=/bin

# export PATH="/bin"

환경 설정 손쉽게 하는 팁
스크립트 파일을 작성합니다.

# vi env_set

#!/usr/bin/sh
export TEMPPATH=/usr/temp

...

이렇게 작성한 다음에 보통 실행을 시킬때 .env_set라고 하면환경설정이 프로그램이 실행이 끝남과 동시에 사라집니다.

. ./env_set_arm

이렇게 앞에다가 도트와 스페이스를 하나 넣어주시면 환경설정이 남아있어서 여러 종류의 환경설정이 필요할때 유용하게 사용하실 수 있습니다.