로케일(Locale)에 관하여...

  1. 로케일(Locale)의 의미
  2.  세계 여러 나라들은 각자 다른 문화(언어, 날짜, 시간 등)을 갖고 있다. 프로그램의
    국제화(Internationalization, 줄여서 i18n)는 사용자로 하여금 프로그램 수행시
    로케일이란 것에 의해 입맛에 맞는 환경을 선택할 수 있도록 만든 것을 말한다.
    예를 들어 어떤 프로그램의 메시지가 여러가지 언어로 주어져 있는 경우 이중에
    어떤 언어의 것을 출력할 것인가를 사용자가 결정할 수 있는 것이다. 그것을 
    가능하게 해 주는 수단이 바로 로케일이다. 이것은 단순히 메시지 뿐만이 아니고
    숫자표현법, 날짜 또는 시간표현법 등 여러가지에 사용될 수 있다. 그것 각각을
    우리는 카테고리(category)라고 부른다. 카테고리에는 LC_COLLATE, LC_CTYPE,
    LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME 가 있다.
    

  3. 로케일 설정방법
  4.  로케일을 지원하는 프로그램의 실행 방식을 선택하기 위해서는 환경 변수 설정을
    이용한다. (카테고리 각각에 해당하는 환경변수는 카테고리 이름과 동일하다.)
    로케일 환경 변수에 관한 정보는 locale이란 명령으로 간단히 얻을 수 있다.
    % locale
    LANG=ko_KR.eucKR
    LC_CTYPE="ko_KR.eucKR"
    LC_NUMERIC="ko_KR.eucKR"
    LC_TIME="ko_KR.eucKR"
    LC_COLLATE="ko_KR.eucKR"
    LC_MONETARY="ko_KR.eucKR"
    LC_MESSAGES="ko_KR.eucKR"
    LC_ALL=
     위에서 ko_KR.eucKR은 로케일 값(locale name)이다. 일반적인 로케일 값의 형식은
    ll[_CC[.EEEE]][@dddd] 이다. ll은 언어(language)를 지정하는 소문자 두 글자 ISO
    639 language code, CC는 지역(territory)를 지정하는 대문자 두 글자 ISO 3166
    country code, EEEE는 코드셋(codeset)을 지정하는 문자셋(character set) 또는
    인코딩(encoding), dddd는 방언 등의 변종을 구별하기 위한 것(modifier)이다. []로
    표시된 내용은 안 쓸수도 있음을 의미한다. 예를 들면 en_US는 미국 영어권, en_CA는
    영어권 카나다, de_DE는 독일의 독일어, fr_FR는 프랑스의 프랑스어를 의미한다.
     아무 로케일도 설정하지 않았을 때 glibc에서의 기본 로케일은 C 또는 POSIX
    (glibc에서는 C 로케일의 alias) 로케일이다. 
    
    % locale -a
    라는 명령을 이용하면 이외에 사용 가능한 로케일의 이름들을 알 수 있다.
     다음은 여러가지 환경변수의 역할(카테고리의 경우에는 동시에 카테고리의 역할)에
    관한 설명이다.
    
      LANG : 모든 카테고리에 대한 로케일 설정을 위한 환경변수이다. 하지만 LC_*
    환경변수보다 우선 순위가 낮다. LC_ALL이 설정이 안 되어 있고 LC_* 값들이 설정이
    따로 설정이 않된 경우 LANG을 변화시키면 LC_ALL을 제외한 로케일 카테고리들의
    값이 변경되지만 LC_ALL이 설정 되어 있는 경우 LANG의 변화는 로케일 카테고리들의
    값에 영향을 주지 않는다.
      LC_CTYPE : 문자 분류(알파벳, 숫자, 한글 또는 소문자, 대문자 등등), 변환,
    대소문자 비교을 위한 로케일 설정을 의미한다. 이것은 예를 들어 fgetwc(), is*(),
    isw*(), mblen(), mbtowc(), wcstombs() 등의 함수에 영향을 줄 수 있다.
      LC_COLLATE : 스트링(string)의 정렬 순서(sort order 또는 collation)를 위한
    로케일 설정을 위해 사용된다. 이것은 예를 들어 strcoll(), wcscoll(), strxfrm()
    등의 함수에 영향을 줄 수 있다.
      LC_MESSAGES : 메시지 표현을 위한 로케일 설정. 메시지의 국제화를 위한
    catopen(), gettext() 등의 함수에 영향을 줄 수 있다.
      LC_NUMERIC : 금액이 아닌 숫자 표현(천단위, 소수점, 숫자 그룹핑 등)을 위한
    로케일 설정. 예를 들어 strtod(), atof().
      LC_MONETARY : 금액 표현(천단위 구분 문자, 소수점 문자, 금액 표시 문자, 그 
    위치 등)을 위한 로케일 설정. 예를 들어 strfmon().
      LC_TIME : 시간과 날짜의 표현(년, 월, 일에 대한 명칭 등)을 위한 로케일 설정
    예를 들어 strftime(), strptime().
      LC_ALL : 모든 카테고리에 대한 로케일 설정을 위한 환경변수이다. 위의 LC_* 및
    LANG의 어떤 것보다 우선 순위가 높다. 그리고 LC_ALL을 설정하면 다른 로케일
    카테고리의 값들이 LC_ALL의 값의 변경되고 LC_ALL설정을 없애면 다른 로케일
    카테고리의 값들은 이전값을 유지한다.
      LANGUAGE : 로케일의 다중 설정을 위해 gettext에서 사용되는 GNU extension 
    환경변수로 LC_ALL보다도 우선순위가 높다. 로케일들은 구분문자 : 을 이용하여
    우선순위가 높은 순대로 나열된다. 예를 들어 LANGUAGE=en_US:ko_KR
      LINGUAS : gettext를 사용하는 프로그램 설치시 지정한 언어들의 메시지만을
    설치하기 위한 환경변수. 구분 문자는 스페이스이다. 예를 들어 LINGUAS="ko ja"
    

  5. 로케일을 지원하기 위한 방법 및 작동 원리
  6.  로케일을 제대로 지원하는 프로그램을 작성하기 위해서는 setlocale()함수를
    이용하여 로케일을 설정하고 확인하여야 한다. setlocale()함수는 헤더 파일
    locale.h 에 정의되어 있으며 그 프로토타입은 다음과 같다.
     char *setlocale (int category, const char *locale);
    이 함수의 역할은 카테고리 category에 대해 로케일 locale을 설정하고 (물론, 사용
    가능한 로케일인 경우), 설정된 로케일값을 리턴하는 것이다.
     locale 부분에 ""을 넣은 다음과 같은 예는
     setlocale (LC_ALL, "");
    적당한 환경변수를 참조하여 로케일을 설정하고 그 값을 리턴한다. 환경변수를
    참조하는 우선순위는 위에서 설명한대로 LC_ALL, 그외 카테고리, LANG변수 순이고,
    변수값을 알아내면 locale.alias(예를 들어, /usr/share/locale/)를 참조한 후
    뒤에서부터 @ . _ 을 단위로 순서대로 잘라가며 사용가능한 로케일을 찾아낸다.
     인수 locale 부분에 NULL을 넣은 다음예는 
     locale = setlocale (LC_ALL, NULL);
    로케일 값을 변경시키지 않고 단지 카테고리에 관한 현재 로케일값을 알아내고자 
    하기 위해 그 리턴값을 사용하는 예이다.
     다음은 함수 setlocale()을 사용하여 임시로 로케일로 변경하는 예이다. (glibc
    manual에 있는 예)
    
         #include <stddef.h>
         #include <locale.h>
         #include <stdlib.h>
         #include <string.h>
         
         void
         with_other_locale (char *new_locale,
                            void (*subroutine) (int),
                            int argument)
         {
           char *old_locale, *saved_locale;
         
           /* 현재 로케일명을 알아낸다. */
           old_locale = setlocale (LC_ALL, NULL);
         
           /* setlocale()의 재호출 의해 변경될 것을 대비해 로케일 이름을 미리 복사해 둔다. */
           saved_locale = strdup (old_locale);
           if (saved_locale == NULL)
             fatal ("Out of memory");
         
           /* 로케일을 변경하고 subroutine을 수행한다. */
           setlocale (LC_ALL, new_locale);
           (*subroutine) (argument);
         
           /* 원래의 로케일로 복귀한다. */
           setlocale (LC_ALL, saved_locale);
           free (saved_locale);
         }
    
     다음은 로케일을 이용하여 날짜/시간을 출력하는 프로그램의 예이다.
    	#include <stdio.h>
    	#include <locale.h>
    	#include <time.h>
    
    	int main(void)
    	{
    		time_t now;
    		struct tm *l_time;
    		char string[256];
    
    		/* 환경변수로부터 시간 관련 로케일을 결정한다. */
    		setlocale(LC_TIME, "");
    
    		/* calendar 시간을 now라는 변수에 저장. 
    		 * 그 값은 1970년 1월 1일 이후부터 지금까지의 초단위 시간 */
    		now = time((time_t *)NULL);
    
    		/* calendar 시간의 다른 유용한 형태를 l_time변수에 저장 */
    		l_time = localtime(&now);
    
    		/* 우리가 원하는 포맷의 시간 포맷을 string이라는 변수에 저장 */
    		strftime(string, sizeof string, "%c", l_time);
    
    		/* 출력 */
    	 	printf("%s\n", string);
    
    		return 0;
    	}
     다음은 위의 파일을 time_test.c라고 저장하고 컴파일하여 c쉘에서 시험하는 
    예이다.
    % gcc -o time_test time_test.c
    % setenv LANG ko_KR.eucKR
    % ./time_test
    2000년 01월 12일 수요일 오후 10시 26분 56초
    % setenv LANG C
    % ./time_test
    Wed Jan 12 22:27:22 2000










최근의 RHEL이나 CentOS 의 기본 locale 은 utf8 이지만 예전 Linux나 AIX나 HP-UX 등의 OS  init.d/script 를 보면 다음과 같은 부분이 있는 경우가 있다.

 

LANG=C
export LANG

 

그간 application이 한글 메시지를 출력할 때 터미널이 한글을 지원 못해 깨져 보일 경우 무의식적으로 export LANG=C 를 입력하여 해결했는데 이게 정확히 무슨 의미인지, C가 맞는 locale 인지, 왜 D 나 E 가 아니라 C 인지 궁금해서 찾아보았다.

 

결론은 LANG 을 "C" 로 설정하는건 locale 을 끄는 의미이고 "C" 는 표준에 있는 locale name 이 맞다고 한다.

locale name 이 "C" 인것은 C 언어 표준중 7.11.1.1 The setlocale function 에 다음과 같이 지정되어 있기때문이다. (C 언어 표준에 있는 내용이라 "C" 인것 같다)

"A value of "C" for locale specifies the minimal environment for C translation;"




출처 - https://www.lesstif.com/pages/viewpage.action?pageId=17105910







Why “LANG=C”? (not D or E or F)

In order to turn off localisation features one should set LANG environment variable to "C".

Why "C"? Where it came from?


In the C programming language, the locale name C “specifies the minimal environment for C translation” (C99 §7.11.1.1; the principle has been the same since at least the 1980s). As most operating systems are written in C, especially the Unix-inspired ones where locales are set through the LANG and LC_xxx environment variables, C ends up being the name of a “safe” locale everywhere.

POSIX specifies that both C and POSIX must be valid locale names, with the same neutral settings.



source - http://superuser.com/questions/219945/why-lang-c-not-d-or-e-or-f










1. Locale

Locale(로케일은) 프로그램을 언어와 국가에 최적화하기 위해서 사용하는 "지역/언어"정보다. 프로그램은 유저(보통 시스템 관리자)가 설정한 locale에 따라서, 입/출력 인코딩을 적용해서 메시지를 출력한다.

로케일관련 패키지는 locales이고, 보조적으로 각 언어별로 language-pack-*패키지가 있다.

2. Locale 목록 확인

locale -a로 운영체제에서 사용할 수 있는 로케일 정보를 볼 수 있다.

1
2
3
4
5
6
7
8
9
10
# locale -a
yundream@yundream:~$ locale -a
C # ASCII
C.UTF-8
POSIX
en_AG
en_DE.utf8 # , , UTF-8 encoding
en_CA.utf8 # , , UTF-8 encoding
en_US.utf8 # , , UTF-8 encoding
ko_KR.utf8 # , , UTF-8 encoding

3. 현재 로케일 정보 확인하기

locale명령으로 시스템의 로케일 정보를 확인할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ locale
LANG=ko_KR.UTF-8
LANGUAGE=ko_KR
LC_CTYPE="ko_KR.UTF-8"
LC_NUMERIC="ko_KR.UTF-8"
LC_TIME="ko_KR.UTF-8"
LC_COLLATE="ko_KR.UTF-8"
LC_MONETARY="ko_KR.UTF-8"
LC_MESSAGES="ko_KR.UTF-8"
LC_PAPER="ko_KR.UTF-8"
LC_NAME="ko_KR.UTF-8"
LC_ADDRESS="ko_KR.UTF-8"
LC_TELEPHONE="ko_KR.UTF-8"
LC_MEASUREMENT="ko_KR.UTF-8"
LC_IDENTIFICATION="ko_KR.UTF-8"
LC_ALL=

LANGLC_* 값들을 설정하지 않았을 때 적용되는 기본 값
LC_ADDRESS
LC_ALLLC_ALL의 값으 LC_*의 값이 override 된다.
LC_TIME시간 출력 양식 설정
LC_TELEPHONE전화번호의 출력 양식 설정
LC_PAPER종이의 크기 형식. 11 x17 inches, A4 등등
LC_NUMBER숫자표현양식. 대부분 소수구분으로 "."을 사용하지만, 어떤 나라는 ","을 사용한다.
LC_NAME이름 표기 형식. first, last name등
LC_MESSAGES시스템 메시지 출력에 사용할 언어
LC_CTYPE대문자, 소문자간의 변환 형식
LC_COLLATE알파벳의 정렬과 관련된 규칙. "C"나 "POSIX" 로케일의 경우 strcmp()를 적용한 것과 같은 결과를 보인다.

4. 로케일별 출력 예제

로케일 관련된 환경변수 설정에 따른 출력 결과

1
2
3
4
5
6
7
# date
2013. 09. 14. () 14:31:54 KST
# export LC_TIME=en_US.utf8
# date
Sat Sep 14 14:34:21 KST 2013

5. 로케일 설정 변경

시스템 기본 로케일 설정은 /etc/default/locale을 수정하면 된다.

1
2
# cat /etc/default/locale
LANG="ko_KR.UTF-8"

6. 로케일 생성

VirtualBox로 Ubuntu 13.04 server 운영체제를 설치했다. 그런데 로케일에 ko_KR.utf8이 설치가 안됐다. 아마도 설치하면서 언어설정을 기본(영어)로 했기 때문인 것 같다. 종종 이런 경우를 경험한다. 특히 AWS에서 리눅스 인스턴스를 올린 후에는 거의 반드시 로케일 설정을 해줘야 한다.

ko_KR.utf8 로케일을 추가해 보자.

1
2
3
4
5
6
7
# locale-gen ko_KR.UTF-8
Generating locales...
ko_KR.UTF-8... done
Generation complete.
# locale -a | grep ko_KR
ko_KR.utf8

이제 /etc/default/locale를 수정하는 것으로 기본 로케일 설정을 변경할 수 있다.

혹은 (bash를 사용한다면).bash_profile을 수정하는 방법도 있다.

# cat ~/.bash_profile
export LANG=ko_KR.utf8








source - http://www.joinc.co.kr/w/Site/Linux/Locale



'System > Common' 카테고리의 다른 글

대용량 데이터 분석 기술 (Big Data Analytics)  (0) 2012.04.26
HP LoadRunner  (0) 2012.04.24
AWK & SED 예제  (0) 2012.04.05
PATH 환경변수 우선순위  (0) 2012.04.05
ssh와 sftp 사용 권한 설정  (0) 2012.04.04
Posted by linuxism
,