검색 엔진의 방문이 늘어나고 있군...

Posted
Filed under 시스템
제가 이쪽에 대해 잘 아는 건 아니지만 윈도우와 리눅스 사이에서 데이터를 옮기다 보면 워낙 많이 겪는 문제라 이참에 아는 한도 내에서 정리를 하려고 합니다. 이 글에서는 윈도우에서 작성한 파일을 리눅스에서 읽었을 때 일어날 수 있는 문제와 해결 방법을 중심으로 이야기를 풀어나가겠습니다. 틀린 내용이 있을 수 있으므로 본문 내용을 너무 믿지 마시기 바랍니다;;

  일단 윈도우는 문자 인코딩에서 코드 페이지라는 것을 사용합니다. 코드 페이지는 IBM이 정의한 문자 인코딩 표인데 문자의 종류(예를 들어 그리스 글자, 한국어 글자, 일본어 글자 등)별로 번호가 있습니다. 즉, 각각의 코드 페이지는 각각의 인코딩 방식을 뜻합니다. 예를 들어 한글 윈도우는 CP949라는 코드 페이지를 사용하며 이를 두고 'CP949 인코딩을 사용한다'라고 할 수 있습니다.

  문제는...이 CP949가 표준 인코딩이 아니라는 것에 있습니다. CP949와 유사한 인코딩으로 EUC-KR이라는 것이 있습니다. 둘이 비슷하여 대부분의 문자가 호환되다보니 CP949와 EUC-KR을 같은 것으로 알고 있는 경우가 많습니다만 사실 CP949는 EUC-KR의 확장판으로서 EUC-KR에서 표현이 불가능한 문자를 표현할 수 있습니다.

CP949 인코딩 구조(출처: 위키피디아)
  위 그림에서 KS X 1003과 KS X 1001 부분을 사용하는 것이 EUC-KR이며 보라색 부분을 추가로 사용하는 것이 바로 CP949입니다. 그러므로 CP949는 EUC-KR에 대해 하위 호환성을 가지고 있습니다.

  그럼 이게 어떻게 문제가 되는지 실제로 한 번 알아보겠습니다. 먼저 윈도우에서 메모장을 통해 "test.txt"라는 이름의 텍스트 파일을 하나 만들고 그 안에 "가나다"라는 내용을 집어넣어 리눅스 서버에 옮긴 후 터미널을 통해 접속하여 그 내용을 출력할 겁니다. 터미널 프로그램은 putty를 이용하겠습니다.

  먼저 서버에 접속 전에 아래의 그림처럼 서버로부터 전송받은 문자 코드 값을 어떤 인코딩 방식으로 변환하여 출력할 것인지 정해야 합니다. 이를 위해 한글 윈도우에서 사용하는 인코딩 방식인 CP949를 입력합니다. 참고로 CP949는 탑다운 목록에 없기 때문에 수동으로 입력해야 합니다.

사용자 삽입 이미지
  그리고 한글을 적을 수 있도록 한글이 있는 폰트를 선택하고 스크립트도 한글로 선택합니다.

  이제 서버에 접속해서 서버의 로케일이 CP949가 아님을 확인하고 파일의 내용을 출력해보겠습니다.
mirashi@myservlab:~$ echo $LANG
ko_KR.UTF-8
mirashi@myservlab:~$ cat test.txt
가나다
  그런데 서버의 로케일이 UTF-8임에도 불구하고 CP949 인코딩을 사용한 텍스트 파일의 내용이 잘 보이는 것을 확인할 수 있습니다. 그 이유는 파일의 내용을 가감 없이 출력만 했기 때문입니다. 이를 쉽게 설명하자면 아래와 같습니다.
  1. 이 파일의 내용은 CP949 인코딩을 사용하여 작성되었다.
  2. 서버는 파일의 16진수 값을 그대로 터미널 프로그램으로 전송하였다.
  3. 전송을 받은 터미널 프로그램은 그 값을 CP949로 인코딩해서 우리에게 보여주었다.
  즉, 파일은 CP949 인코딩으로 작성됐고 앞서 처음 터미널을 설정할 때 서버로부터 전송받은 문자 코드 값을 CP949로 변환하여 화면에 보이도록 설정했기 때문에 서버의 로케일이 무엇이 됐던 간에 제대로 된 결과를 볼 수 있는 겁니다.

  그렇다면 이제 아무것도 문제가 없는 걸까요? 위는 어디까지 파일의 내용을 단순히 출력했을 때만 해당되는 이야기입니다. 만약 지금 상황에서 파일이나 디렉토리를 한글로 만들면 어떻게 될까요?
mirashi@myservlab:~/test$ touch 한글
mirashi@myservlab:~/test$ ls
?畸?
  이제 문제가 보이기 시작했습니다. 아까 putty를 설정할 때 사용할 캐릭터 셋을 CP949로 설정했기 때문에 '한글'이라는 문자열을 넘겨줄 때는 CP949로 넘어갑니다. 그런데 지금 서버에서 사용하고 있는 인코딩 방식은 UTF-8입니다. 저(=터미널)는 '한글'이란 문자열을 CP949의 코드로 넘겨주고 서버는 일단 불만 없이 이를 파일명으로서 파일 시스템에 저장합니다. 그 후 ls로 파일명을 출력하도록 하니 UTF-8를 사용하는 시스템 입장에서는 이해할 수 없는 문자 코드였기 때문에 이상한 결과가 출력되는 겁니다. 이는 로케일을 EUC-KR로 바꾸면 제대로 출력된다는 것을 통해 증명할 수 있습니다.
mirashi@myservlab:~/test$ LANG=ko_KR.UTF-8
mirashi@myservlab:~/test$ ls
?畸?
mirashi@myservlab:~/test$ LANG=ko_KR.EUC-KR
mirashi@myservlab:~/test$ ls
한글
  편법으로 ls를 사용할 때 제어 문자도 강제로 출력하게 하는 --show-control-char 옵션을 사용하면 문자 코드를 해석하지 않고 그대로 출력하기 때문에 로케일이 UTF-8라도 제대로 된 출력을 볼 수 있긴 합니다.
mirashi@myservlab:~/test$ ls
?畸?
mirashi@myservlab:~/test$ ls --show-control-char
한글
  하지만 이건 어디까지나 편법일 뿐 정상적인 방법이라고 볼 수 없습니다. 이런 문제는 파일을 편집하려고 할 때 더욱 부각됩니다.

  위는 "가나다"라는 내용이 CP949로 저장되어 있던 test.txt 파일을 vi 에디터로 열었을 때 볼 수 있는 상황입니다. 이제는 문자 코드를 읽어서 로케일에 설정된 인코딩 방식에 따라 보여주기 제대로 보는 것 조차 불가능합니다.(단, 옵션들을 통해 가능하긴 합니다) 참고로 아래에 글씨가 깨지는 건 현재 로케일이 UTF-8로 되어 있는데 터미널에서는 CP949로 번역하고 있기 때문에 그런 겁니다.

  위는 서버의 로케일을 EUC-KR로 바꾼 후 vi 에디터를 다시 실행한 모습입니다.

사용자 삽입 이미지
  이제 제대로 표시는 되는군요. 그런데 또 다른 문제가 있습니다. 지금 사용하고 있는 인코딩 방식은 EUC-KR이며 이 인코딩 방식은 표현하지 못하는 한글들이 있습니다. '똠' 같은 글자도 그런 글자 중 하나입니다. 이는 vi 에디터에서 인코딩과 관련된 몇 가지 명령어를 통해 해결할 수 있긴 하지만 근본적으로 이런 작업이 필요하다는 사실 자체가 문제라고 볼 수 있겠죠.

  앞서 본 모든 문제들은 한글 윈도우(더 나아가 전 세계의 모든 OS)가 세계 표준이라고 할 수 있는 UTF-8 인코딩 방식을 사용하면 완전히 해결되겠습니다만 만약 진짜로 그렇게 되면 기존 데이터들로 인해 한 동안 대혼란이 발생할 거고 그로 인한 비난은 (비록 자신들이 스스로 자초한 거지만)고스란히 MS가 받을 테니 그들이 그런 선택을 할 것이라고 기대하긴 어렵습니다. 결국 한 동안은 이런 문제가 지속될 것 같군요.

2011/07/24 03:08 2011/07/24 03:08