vi 에디터에서 ^M 문자 한번에 모두 지우기 ( ^M, ^L을 이해하자)

윈도에서 개발하던 개발자 혹은 SE들이 Unix로 전향(?)한 뒤 고생하는 문제중에 하나가 바로 텍스트파일의 포맷차이로 인한 문제다.  또한 FTP로 파일을 Upload하거나 Download 할 때 Binary 모드와 ASCII 모드의 차이를 이해하지 못하는 엔지니어들이 종종 이 문제로 인해 사고를 치곤한다.

Unix/Linux의 /etc/passwd 파일을 FTP를 통해 윈도PC로 다운로드 받을 때 Binary 모드로 다운로드를 받게 되면 다음과 같이 텍스트파일이 깨져(?) 보인다.


하지만 이것은 파일이 깨진것이 아니다. ASCII 모드로 passwd 파일을 다운로드 받으면 정상적으로 보인다.

이 문제(?)는 윈도와 Unix/Linux의 텍스트파일, 엄밀하게 말하면 ASCII 파일의 포맷차이로 인해 발생하는 문제다. 그 포맷의 차이란 바로 줄바꿈의 표기방법의 차이로 인한 것이다.

Unix의 경우 텍스트편집기인 vi에서 한줄을 모두 입력한 뒤 <ENTER> 키를 누르면 해당 라인의 끝에 ^L (ASCII코드 10번, LineFeed) 하나만 넣어 줄바꿈이 되었음을 표시한다.
하지만 Dos/windows의 경우 ^M^L 두개를 넣어서 줄바꿈을 표시한다. ^M은 아스키코드 13번의 문자로서 캐리지리턴(Carriage Return)을 의미한다. 즉 커서를 1컬럼으로 돌린다는 것을 의미한다.

FTP를 이용해 줄바꿈이 ^L(라인피드)만으로 입력되어 있는 Unix의 텍스트파일을 다운로드 받으면 FTP프로그램이 자동으로 ^L을 ^M^L로 변환하여 저장해 준다. 따라서 노트패드로 해당 파일을 열었을 때 위의 화면과 같이 깨져보이지 않고 정상적으로 줄바꿈이 된것 처럼 보인다. 하지만 실제로는 파일의 크기가 커진다. (행의 수만큼)

따라서 PC에서 수정 후 업로드를 할 때도 반드시 ASCII 모드로 업로드를 해야한다. 만약 바이너리 모드로 업로드를 하게되면 ^M^L이 그대로 업로드 된다. 따라서 Unix의 vi로 해당 파일을 열게되면 다음과 같이 보인다.


윈도에서는 인식되어 줄바꿈 표시의 일부로 인식되던 ^M (캐리지리턴문자)가 줄바꿈으로 인식되지 않고 화면에 표시되어 버린다.

만약 위외 같이 패스워드파일을 쉽게 편집하기 위해 FTP를 이용해 다운로드 받은 뒤 수정하고 바이너리모드로 잘못 업로드하게 되면 대형사고가 발생하게 된다.
아무도 텔넷, FTP, rlogin 등으로 접속하지 못하는 상태가 되어버린다. 왜냐하면 패스워드 파일의 맨 끝의 쉘을 지정하는 부분이 제대로 인식되지 못하여 no shell 메시지가 발생하면서 쉘을 실행하지 못하기 때문이다.

^M 한번에 모두 지우기

이 ^M이 왜 생기는지는 모두 이해했으리라 생각된다. 그렇다면 이 수많은 ^M을 한번에 지우는 방법은 없을까...   당연히 있다.

vi로 해당 파일을 열고 다음의 명령을 수행하면 아주 간단하게 지울 수 있다.


다만 키보드에서 ^M 을 그냥 ^ 키와 M을 입력해서는 인식되지 않는다. ASCII 코드의 13번 문자인 CR은 키보드의 Control키를 누른상태에서 v와 m을 차례대로 입력해야 입력할 수 있다.

%s/^M$//g

이 명령을 기억하라.

참고로 인터넷에 떠다니는 ASCII코드표를 첨부한다.


사족 : 아주 오래전 Ingres라는 데이터베이스 S/W의 기술지원을 할 때 종종 사용했던 팁이었는데 한참을 써먹지 않았더니 기억이 나지를 않아 애를 먹었던 적이 있다. ㅋㅋ





댓글(0)

Designed by JB FACTORY