2009년 1월 31일 토요일

현재 유닉스 스타일 파일시스템의 의미는

리눅스에서 많이 사용하고 있는 File Hierachy Standard 는 전통적으로 유닉스에서 사용되던 표준 파일 시스템을 명백히 표준으로 정의한 것이다. 유닉스나 리눅스 사용자라면 익숙하다 못해 친근하기까지 한 /lib, /bin, /sbin, /usr/bin, /usr/share, /usr/lib 따위의 구조는 영원히 없어지지 않는 성역이라고 생각하기 쉽지만, 이제 근본적으로 바뀔 때도 되지 않았을까? 과거의 유닉스 플랫폼의 사정이 오늘날에도 적용이 될까?

유닉스 파일 시스템의 구조는 몇 가지 목적을 가지고 만들어졌다.
  • 부팅과 최소한의 관리에 필요한 파일 (/), 시스템 설치 파일 (/usr), 사용자 설치 파일 (/usr/local) 구분으로 공유 가능
  • 아키텍처 의존 파일과 (/usr/lib) 독립 파일을 (/usr/share) 구분해서 독립 파일을 여러 아키텍쳐 컴퓨터 사이에 네트워크로 공유 가능
  • 읽기 전용 파일시스템, 시스템 설정, 데이터 파일 시스템 구분 (/usr, /etc, /var 구분)

정말 공유하는 사람이 있나요?

큰 목적은 "파일 시스템의 공유 가능"이다. 부팅에 필요한 파일은 컴퓨터마다 필요하지만 /usr 아래의 대부분은 공유할 수 있다. 아키텍처가 다른 컴퓨터 사이에는 일부 파일은 공유할 수 없지만 /usr/share 따위는 공유할 수 있다. 오호라! 진짜? 요즘 세상에 이렇게 공유하는 곳이 있을까?

거의 10년 전 학교의 컴퓨터 실에는 이런 식으로 설정된 몇 대의 스팍 서버가 있었다. 하지만 이러한 멋진 구조 덕분에 최악의 안정성을 자랑했다. single point of failure, 한 머신이 죽으면 그 파일 시스템을 공유하는 모든 서버가 동작 불가능이었다. 실제로 그 서버 구성의 최대 장점은 홈 디렉토리의 공유였지 /usr 따위의 공유가 아니었다. /usr의 공유는 /usr 파일 시스템의 크기가 크고, 스토리지의 가격이 비쌀 때 가치가 있지만 용량도 커지고 가격도 내려간 지금의 하드디스크에서 /usr 파일 시스템이 공유할 만큼의 가치를 지니지 않는다.

그리고, 오늘날의 실정을 여러 모로 보면 리눅스 파일 시스템에서 /usr를 공유할 수 있다는 말은 거짓말이다. /usr/include를 보면 각 아키텍처에 의존하는 값이 잔뜩 들어 있는 헤더가 가득하고, 패키징 시스템은 /usr/share와 /usr/lib 에 동시에 파일을 설치한다.

정말 /usr 파일 시스템을 읽기 전용으로 별도 파일 시스템에 마운트해서 여러 컴퓨터 사이에 같은 아키텍처인지 아닌지에 따라 /usr/share와 /usr/lib을 구분해서 공유하는 곳이 있기는 할까? 아무리 네트워크 파일 시스템을 널리 사용하는 곳도 홈 디렉토리 공유나 대용량 스토리지 구현을 위해 사용하지 "비교적 작은" 크기의 /usr 디렉토리를 읽기 전용으로 마운트하려고 사용하는 곳은 본 적이 없다. 10년 전의 그 학교 컴퓨터 실에서도 아키텍처별로 구분하지는 않았다.

과거의 잔재

한편 /usr/X11R6 및 /usr/games라는 구조가 남아 있는데  /usr/X11R6는 X11 및 CDE/XView 따위가 굉장히 커다란 소프트웨어였던 시절에나 의미있는 구분이었다. 이제 X.org 프로젝트는 이 구조를 따르지 않는다. (/usr/X11R6/bin은 /usr/bin으로 가는 심볼릭 링크이다.)  /usr/games, /var/games같은 경우에는 BSD의 잔재인데 FHS 문서에 따르면:
The separation allows local control of backup strategies, permissions, and disk usage, as well as allowing inter-host sharing and reducing clutter in /var/lib
백업 방식을 다르게 하기 위해서, 권한을 다르게 하기 위해서, 컴퓨터 사이에 점수 따위를 공유하기 위해서, /var/lib 크기를 줄이기 위해서라고 되어 있다. 이 역시 오늘날의 실정과 맞지 않는다.

바꿀 필요가 없으니까?

굳이 전통적으로 잘 써 왔고 각종 툴이 잘 지원하는 지금의 파일 시스템 구조를 바꿀 필요가 있을까?

일단 현재의 문제는, 소프트웨어 바이너리 패키지의 유연성이 떨어진다. 현재 조금 복잡도가 높은 리눅스 소프트웨어들은 빌드타임에 데이터가 들어 있는 디렉터리가 보통 하드 코딩되어 있다. RPM 패키지의 경우 /usr, /usr/local을 선택할 수 있는 relocatable 패키지를 만들 수 있는 기능이 있지만 이렇게 경로를 하드 코딩하는 애플리케이션들은 relocatable하게 만들기 어렵다. 현재의 파일 시스템에서는 바이너리 패키지만으로 같은 애플리케이션의 여러 버전을 동시에 설치하거나 사용자에 따라 다른 애플리케이션을 설치한다거나 하는 유연성이 없다.

애플리케이션별로 별도의 경로로 설치하면 명령어 실행 경로라든지 ($PATH), 맨페이지, 폰트처럼 한 프로그램이 사용하는 데이터를 여러 패키지에서 설치하는 경우에 문제가 생기지만, 해결 방법은 있다. 한 디렉토리 안에 파일을 몰아 넣지 않더라도 파일시스템의 기능을 통해 여러 경로의 내용들을 한 곳으로 자동으로 합치는 기능이 있다. (이름이 생각이 안 나서 검색 불가...)

2008년 12월 27일 토요일

오늘날 아래아의 용도는

구글 뉴스에 뜬 오늘자 신문을 긁어 보았다.

"복지ㆍ노동"

오늘날 아래아는 "복지·노동"처럼 가운뎃점의 폭이 작은 게 마음에 안 드는 분들을 위한 대체품.

(모음 "ㅣ"를 세로줄 대신 쓰는 경우도 심심치 않게 볼 수 있다.)

2008년 11월 5일 수요일

hunspell 한글 검사 실험 - proof of concept

개요는 생략.

hunspell 프로그램이 한글 단어의 edit distance를 계산할 수 있으려면 내부 처리는 모두 첫가끝 코드로 바꿔야 한다. 프로그램을 바꾸기는 어려우니 첫가끝 코드로 변환하고 복원하는 간단한 필터 작성. 만만한게 파이썬에 들어 있는 unicodedata.normalize.

#!/usr/bin/env python
import unicodedata
import sys

while True:
    line = sys.stdin.readline()
    if not line:
        break
    line = unicodedata.normalize('NFC', line.decode("UTF-8")).encode("UTF-8")
    sys.stdout.write(line)
#!/usr/bin/env python
import unicodedata
import sys

while True:
    line = sys.stdin.readline()
    if not line:
        break
    line = unicodedata.normalize('NFD', line.decode("UTF-8")).encode("UTF-8")
    sys.stdout.write(line)

그리고 hunspell의 언어 추가에 필요한 두 가지 데이터, 사전과 affix 파일을 작성한다.

완전한 사전 데이터가 있을 리가 없고... 일단 마구 생각나는 단어 "가방", "발", "컴퓨터"를 입력해 본다. 이 파일은 hunspell에서 직접 읽어들이기 때문에 첫가끝으로 변환해야 하는데..  앞에서 작성한 필터로 변환한다.
3
가방/JS
발/JS
컴퓨터/JS

AFF 파일 작성, 욕심은 자제하고 조사 규칙만 입력한다. 원래는 용언의 어간과 어미를 넣어보려고 했으나.. proof of concept으로 명사 + 조사의 형태의 규칙만 만들어 본다. 받침이 있고 없고에 따라 달라지기 때문에 모음과 자음 목록을 첫가끝으로 입력해야 하는데, 좀 성가시므로 gucharmap을 이용했다.
SET UTF-8
LANG ko_KR
FLAG long

TRY ᄀᄁᄂᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ
WORDCHARS ᄀᄁᄂᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ

# 조사
SFX    JS    Y    9
SFX    JS    0    에    .
SFX    JS    0    가    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ]
SFX    JS    0    이    [ᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]
SFX    JS    0    를    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ]
SFX    JS    0    을    [ᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]
SFX    JS    0    는    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ]
SFX    JS    0    은    [ᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]
SFX    JS    0    로    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵᆯ]
SFX    JS    0    으로    [ᆨᆩᆪᆫᆬᆭᆮᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]

그리고 테스트를 위해 커맨드라인을 첫가끝으로 변환해서 hunspell에 처리한 다음 다시 음절로 바꾸는 스크립트 작성.
#!/bin/sh
echo $* | ./syl2jamo.py | hunspell -d ko_KR | ./jamo2syl.py

몇 번의 시행착오 끝에 hunspell을 이용한 초보적인 한글 맞춤법 검사 동작!
duncan:~/hacks/hunspell$ ./test.sh 가방
Hunspell 1.2.6
*
duncan:~/hacks/hunspell$ ./test.sh 가방이
Hunspell 1.2.6
+ 가방
duncan:~/hacks/hunspell$ ./test.sh 가뱅
Hunspell 1.2.6
& 가뱅 1 0: 가방

duncan:~/hacks/hunspell$ ./test.sh 따방
Hunspell 1.2.6
& 따방 1 0: 가방

duncan:~/hacks/hunspell$ ./test.sh 컴퓨터가
Hunspell 1.2.6
+ 컴퓨터

duncan:~/hacks/hunspell$ ./test.sh 컴퓨터이
Hunspell 1.2.6
& 컴퓨터이 2 0: 컴퓨터에, 컴퓨터

duncan:~/hacks/hunspell$ ./test.sh 컴퓨방
Hunspell 1.2.6
& 컴퓨방 2 0: 컴퓨터, 가방

duncan:~/hacks/hunspell$ ./test.sh 발로
Hunspell 1.2.6
+ 발

duncan:~/hacks/hunspell$ ./test.sh 발으로
Hunspell 1.2.6
& 발으로 3 0: 가방으로, 발로, 발


실제 활용할 수 있을 정도로 끌어올리기에는 할 일이 많다. 다른 프로그램과 연동을 고려하면 첫가끝 변환 코드는 실행 파일에 내장해야 한다. 또 우리말 형태론에 맞게 주의깊게 접두어/접미어 규칙이 작성되어야 한다. (복잡한 용어 어미 변화도 가능해 보인다.) 단어별로 특성이 기술된 단어 사전을 축적하는 게 가장 시간이 오래 걸리는 일이다.

하지만 hunspell로 처리할 수 있다는 건 확인할 수 있었다. 오픈오피스와 파이어폭스 사용자의 피드백을 이용할 수도 있다는 점에서 별도의 프로그램을 작성하는 것보다는 더 가능성 있는 방향으로 보인다.

2008년 11월 3일 월요일

안드로이드폰 G1의 티보이제이션

구글 그룹스에서 Q&A 중의 구글 관계자의 말에 따르면,

The G1 is aimed at end users, not system developers. For user security reasons the G1 will only accept properly signed system images. I'm not sure, in this case, who 'owns' the key, whether it is the carrier or the manufacturer, but one or both of them handle insuring system images are signed.

G1은 일반 사용자용 제품이지 시스템 개발자가 사용하는 게 아니예요. 보안때문에 G1에서는 올바르게 서명한 시스템 이미지만 받아들입니다. 이 경우에는 누가 그 키를 "소유"하는지, 즉 통신사인지 제조사인지 확신하지 못하겠군요. 어쨌든 이 둘 중의 하나 혹은 둘 모두에서 시스템 이미지의 서명을 관리합니다.

Cheers,

Justin
Android Team @ Google

이 말은 즉슨, 커널 및 시스템 프로그램들의 소스코드는 오픈되어 있으나 그 소스코드를 바꾸더라도 T-Mobile이나 HTC가 가지고 있는 디지털 키로 서명하지 않는 한 실제 장비에는 돌릴 수 없다는 뜻이다. 전형적인 티보이제이션이다. G1은 기대와는 달리 오픈 플랫폼이 아니다.

구글 혹은 T-모바일쪽의 이러한 결정이 사악하느냐 (be evil) 아니냐를 떠나서, 컴파일해 봤자 실제 장비에서 돌릴 수 없는 소스코드라면, 안드로이드의 소스 코드를 오픈한 게 과연 무슨 의미가 있는 걸까? 휴대폰 개발사에 소속되어 개발용 폰을 받지 않는 한, 안드로이드의 시스템 코드 개발자들은 안드로이드 SDK에 들어 있는 에뮬레이터의 한계에 갇힐 수밖에 없다.

2008년 9월 5일 금요일

크롬에 액티브엑스라니

"액티브X와 공존 모색"…구글, 웹브라우저 시장 '초강수'

액티브엑스를 정확히 어떻게 돌리겠다고 한국의 웹 환경을 위해 액티브엑스를 지원한다는 발언을 한 건지 모르겠는데.. 어떻게 만들던 간에 32비트 x86 MS Windows 전용이 되는 걸 피할 수 없다.

지금 MS 전용 브라우저를 만들어서 MS를 넘어서 보겠다는 얘기를 하고 있는 건가? ("`크롬`은 MS 잡을 대항마" 에릭 슈미트 구글 CEO, FT와 인터뷰서 도전 시인) 아니면 악성코드의 매개체였던 기술을 구현해서 MORE SECURE한 ("Google on Google Chrome" comic book) 브라우저를 만들어내겠다는 건가?

아마도 크롬의 소스가 공개된 걸 국정원이 발견하면 보안용으로 못 쓰게 만들 것 같은데 (리눅스 보안 제품 국정원 차별 논란), 그러면 한국을 위해 closed source로 만들 지도?


2008년 8월 31일 일요일

지역화 관련 코드 표준들


ISO 639 - 언어 코드. 2글자의 알파벳 코드. 한국어는 KO. (KR이 아니다.)

ISO 639-2 - ISO 639와 마찬가지로 언어코드이지만 3글자 코드이다. 한국어는 KOR이다. tut(Altaic), ine(Indo-European)처럼 특정 언어가 아닌 언어군을 가리키는 코드까지 포함되어 있고, tlh(Klingon, 스타트렉의 외계인이 쓰는 언어)같은 인공어도 들어 있고, 고대와 현대의 언어를 구분해 놓는 등 좀 의문이 드는 코드가 다수 들어 있다. 가장 문제라고 할 수 있는 부분이, terminology use와 bibliography use에 사용하는 코드를 별도로 구분해 놓아 23개의 언어에 대해서 T 코드와 B 코드가 다르다. (독일어의 경우 T 코드는 deu, B 코드는 ger.) B 코드는 당시의 도서관 시스템들이 기존에 분류 기준으로 사용하고 있는 코드를 그대로 수용한 결과이다. 마이크로소프트가 OS에 사용하는 언어 코드가 3글자라서 ISO 639-2가 아닌가 오해하곤 하지만 MS가 임의로 만든 코드이다.

ISO 639-3 - 또 다른 언어 코드. 역시 3글자 코드이고 639-2보다 훨씬 더 확장되었다. 한국어는 마찬가지로 KOR. 하지만 문제의 B/T 코드 구분은 없어지고 T 코드만 사용한다, 언어군을 가리키는 코드도 없어졌다. (클링온은 남아 있음.)

ISO 3166 - 국가 코드. 주권국이 아닌 식민지, 자치 지역, 남극같은 곳에도 코드가 있기도 하다. alpha-2 코드는 대한민국이 KR. (KO가 아니다.) 국가 체제는 어느날 갑자기 분리독립을 하거나 통일/병합되거나 개명하거나 하는 식으로 바뀔 수 있는 것이라 끊임없이 개정되어 왔다.

ISO 3166 alpha-3 - ISO 3166의 subset으로 3글자 코드이고 대한민국은 KOR. 국가 대표 선수들의 이름표도 그렇고, 유닉스/리눅스 L10N에 관련된 사람이 아니라면 2글자 코드보다는 3글자 코드를 일상생활에서 더 많이 볼 수 있다.

ISO 3166 numeric - ISO 3166의 subset으로 3글자의 숫자 코드이다. 대한민국은 410.

ISO 3166-2 - 국가 코드가 아니라 세부 지역 코드이다. ISO 3166 코드 뒤에 세부 지역 코드를 대시로 연결한다. 알파벳이나 혹은 숫자 1글자에서 3글자 사이의 코드로 표기한다. 미국의 주 따위가 대표적으로 미국은 US-TX(텍사스)처럼 우편 약자를 사용한다. 한국에 해당하는 코드는 ISO 3166-2:KR subset에 정의되어 있는데 광역 자치단체별로 구분되어 있고 세부 지역코드는 숫자를 사용한다. 서울은 KR-11, 대전은 KR-30. 이 부분도 각 지역의 행정 체계의 변화에 따라 끊임없이 개정된다.

ISO 15924 - 문자 (script) 코드. 4글자의 알파벳 혹은 숫자 코드이다. 라틴 문자는 통틀어서 Latn이고 한자는 공통으로 Hani가 있는 반면에 중국어 간체는 Hans 번체는 Hant로 구분되어 있다. 한글은 문자코드는 Hang, 숫자코드는 286이다. Hang의 alias로 Kore/287도 있다.

ISO 4217 - 화폐 코드. 흔히 국제 환율 얘기할 때도 많이 쓰는 코드이다. 원화는 KRW.

RFC 4646 - HTML/XML에 사용하는 언어 표기 방법. xml:lang 따위가 대표적이다. ISO 639, ISO 15924, ISO 3166 문자 코드를 순서대로 대시 기호로 연결한다. ISO 639는 소문자, ISO 3166은 대문자로 쓰고, ISO 15924는 첫 글자만 대문자로 쓴다. ISO 639 뒤의 코드를 생략할 수 있고, 중간의 ISO 15924 코드만 생략할 수도 있다. 즉 한국어라면 "ko", "ko-KR", "ko-Hang-KR", "kor", "kor-KOR", "kor-Hang-KOR" 따위로 쓸 수 있다.


2008년 7월 5일 토요일

우분투 런치패드 번역의 BSD 라이센스 전환의 문제

최근 우분투 런치패드는 런치패드에 들어 있는 번역문에 대해 BSD 라이센스로 확인하는 작업을 하고 있다. 일정은 없지만 동의하지 않은 번역문은 런치패드 시스템에서 지워질 예정이다.

이러한 조치는 런치패드의 번역문들이 라이센스를 명확히 하지 않는다는 비판과 더불어, 번역문을 여러 프로그램 사이에 공유할 때 생기는 라이센스 문제에 대한 해결책으로 보인다. (예를 들어 GPL 프로그램의 번역문을 LGPL 프로그램에 사용하는 경우처럼.)

하지만 왜 하필 BSD이며, 왜 BSD가 아니면 시스템에서 지운다는 걸까?

첫째로 과연 GPL 소프트웨어의 번역을 BSD로 하는 게 가능한 것인가 의문을 갖게한다. 원문은 GPL 라이센스로 배포되는 프로그램의 소스코드에서 xgettext 프로그램을 통해 추출한 것이고 번역문은 파생 작업이라고밖에 할 수 없다. GPL 코드에서 추출한 템플릿을 번역한 번역문의 라이센스를 BSD로 한다는 게 가능한 것일까?

또 실제적으로 런치패드의 온라인 번역 시스템이 훌륭하긴 하지만 여전히 훨씬 더 많은 번역문들이 이 시스템 밖에서 만들어져서 런치패드 시스템으로 import되고 있다. 런치패드에 들어 있는 번역문의 대다수는 런치패드에서 시작한 번역문이 아니라 외부에서 import한 번역문을 보완한 정도이고 이렇게 GPL 번역문을 고쳐서 만들어진 결과물을 BSD 라이센스라고 할 수는 없다. 이러한 모든 번역을 지우고 런치패드 내부에서 scratch부터 시작할 것인지?

그리고 GPL은 GPL의 가치가 있다. 나는 내가 번역한 번역문이 해당 소프트웨어의 라이센스를 따르게 할 뿐, 일부러 번역문에 BSD 라이센스를 사용할 생각은 전혀 없다. GPL의 파생작업에 대한 라이센스 조항을 좋아하든 싫어하든 이 GPL 조항은 자유소프트웨어 발전에 대단히 큰 역할을 했다. 런치패드 시스템에서 사용하려고, 호환성때문에 GPL이었을 때의 장점을 버리고 BSD를 택한다는 건 받아들이기 힘들다.

몇몇 언어의 그놈/데비안/KDE 번역 팀들은 런치패드 시스템의 편리함때문에 공식적인 번역 도구로 사용하고 있다. (한국어 번역팀은 아님.) 런치패드의 이러한 조치는 이 팀들이 계속 런치패드에서 작업해야 하는지 고민하게 만들었다. 번역문 사이의 호환성이 문제라면 좀 수고를 하더라도 라이센스 호환성 문제를 처리하도록 시스템을 구현할 수도 있지 않을까? 왜 BSD로 통일해야 하며 그게 아니면 시스템에서 지워야 할까? 이러한 결정은 지금까지 훌륭히 번역 작업을 해 온 런치패드의 발목을 잡게 될 것이다.