damn encoding

요즘 vim을 자주 사용하면서 SSH를 통한 원격 클립보드 기능을 구현하는 도중에 분명 다른 터미널에서 netcat을 이용하여 받았을 때 에는 정상적으로 터미널에 한글이 표시되지만, iTerm의 단축키를 이용해서 Coprocess에서 받는경우 한글이 이상하게 깨져버리는 현상을 발견 해서 해결하기 까지의 삽질 과정을 적어본다.

급하게 해결방법이 필요해서 찾아온 사람이라면 건너뛰기를 누르거나 그냥 스크롤을 내리면 될 것 같다.


추측 1. vim의 인코딩 문제?

우선 단순하게 vim플러그인으로 레지스터에 저장 되어있는 텍스트를 전송하도록 했기 때문에 vim의 인코딩 처리 때문에 문제가 생긴것이 아닌지 확인해 보았다.

기존 플러그인 코드에서 버퍼를 설정하는 부분에 setlocal encoding=utf-8setlocal fileencoding=utf-8 을 추가해 확실하게 utf8 인코딩을 버퍼를 저장하게 해보았다.

플러그인 설정 코드

하지만 코드를 수정하고 :source 명령어로 다시 불러와서 재시도 해보아도 고쳐지지 않았다.


추측 2. 리눅스 locale의 문제?

맥북 개발환경에서는 최대한 한글과 관련된 개발 이슈를 최소화 하기 위해서 locale 을 en_US.UTF-8로 해둔 상태이다.

mac locale

그런데 리눅스 locale 설정을 보니 무슨 이유에서 인지는 몰라도 ko_KR.UTF-8 로 설정이 되어 있었다. 그래서 아래 명령어로 매킨토시 개발환경과 locale을 맞춰주었다.

export LANG="en_US.UTF-8"

Linux locale

하지만 역시 해결되지 않았다.


추측 3. Netcat의 전송문제?

혹시 Netcat이 한글을 전송하는 과정에서 인코딩에서 에러가 있거나, 무언가 패킷이 손실 된다거나 하는 오류는 아닐까 하고 추가적으로 점검했다.

임시저장 파일에서 데이터를 읽어 파이프라인으로 통과시켜 base64로 인코딩 전송하게 하고, 패킷 손실 문제가 있는지 확인해보았다.

cat tempfile | base64 | nc localhost

다른 터미널 탭을 열어서 수신 데이터를 보았는데, 맥에서 base64 파일을 인코딩 한 결과와 1자도 틀리지 않고 같게 나왔다. 그렇다면 리눅스에서 전송된 데이터에는 전혀 문제가 없었다는 이야기다. 결론적으로는 클라이언트인 iTerm에서 문제가 발생한 것이라는 결론에 다다를 수 있었다.


해결

iTerm2 환경설정

특이한 점은 iTerm의 환경설정에서 UTF-8로 설정이 되어있는 것을 확인하였지만 계속 한글이 깨져서 나타나는 현상이 있었다는 것이다. 그러던 중에 알아낸 것은 다른 탭을 연 상태로 Netcat을 통해 통신한 것은 터미널에 정상적으로 나타나는것을 알게 되었다.

Coprocess로 돌아가는 서브 쉘과 환경설정의 인코딩 설정이 따로 놀고 있었다는 이야기다…

but why

결국 간단하게 export LANG="en_US.UTF-8"을 단축키 Coprocess 코드 앞에 추가해 주었더니 깔끔하게 해결할 수 있었다.

변경전

nc -l localhost 7331 | base64 -D | pbcopy

변경후

export LANG="en_US.UTF-8"; nc -l localhost 7331 | base64 -D | pbcopy


프로그래밍에서 한글로 골치 썩이는 일이 많은 것 같은데 이건 그냥 영어권 개발자들이 관심이 없어서 그런 것 같다..

UTF-8 everywhere 가 괜히 나온 이야기가 아닐거다. UTF-8 Everywhere

위에서 언급한 플러그인은 아마 조만간 조금 더 정리하고 나서 GitHub를 통해 배포 할 수 있을것 같다. 쓸 사람이 있을지는 모르겠지만…