윈도우에서 메모장으로 작성한 Bash 스크립트 파일을 리눅스에 넣어 돌리면 오류가 발생합니다. 그 이유는 DOS와 UNIX 계열의 개행 방식이 서로 다르기 때문인데요, 눈에 보이지는 않지만 각 줄의 마지막에는 개행을 위한 문자가 들어있는데, 윈도우는 CR과 LF를 함께 사용하지만 리눅스는 LF만 사용하기 때문에 문제가 발생합니다.

CR은 Carriage Return을 말하며 커서를 제일 앞으로 보내는 역할을 합니다. LF는 Line Feed를 말하며 줄바꿈을 의미합니다. 각각 정규표현식에서는 \r, \n 으로 표현되며, 윈도우의 경우 라인 끝에 \r\n이 붙지만 리눅스는 \n만 붙습니다.

따라서 리눅스에서 작성한 파일을 윈도우에서 메모장으로 열어보면 줄이 전부 붙어있고 대신 문장 끝에 이상한 문자가 보이게 됩니다. (워드패드는 괜찮습니다.)


비슷한 이유로 윈도우에서 작성한 파일을 리눅스에서 열어보면 눈에 보이지는 않지만 끝에 CR이 쓸데없이 붙어있어서, Shell 스크립트 파일을 돌리면 오류가 발생하게 됩니다. 아래 보시면 \r 때문에 command not found 에러가 많이 발생하고 있습니다.


vi에서 -b 옵션을 주면 CR문자가 끝에 ^M 으로 표시된 것을 확인할 수 있습니다.


어쨌든 사설은 그만두고, 이 글의 제목대로 윈도우에서 작성한 Shell 스크립트가 리눅스에서 에러나는 경우 해결방법을 알려드리겠습니다. 방법은 무수히 많습니다. 그러니까 각 라인 끝에 있는 CR 문자를 제거해주시면 되는데요

저는 여러가지 방법 중에 sed로 하는 방법을 소개해드립니다. 제가 리눅스에서 가장 좋아하는 명령어 몇개 중 하나가 바로 sed입니다. 정규표현식과 조합을 하면 정말 많은 작업을 편리하게 해낼 수 있습니다.

DOS => UNIX
예제) sed -i -e 's/\r$//' test.sh

위 명령어는 test.sh 파일에서 \r$ 부분을 찾아 제거하겠다는 뜻입니다. $는 정규표현식에서 라인의 끝을 의미하므로 \r$는 "라인의 끝에 있는 CR 문자" 를 의미하게 됩니다.

여담이지만 위와는 반대로 CR문자를 추가해줄 수도 있겠죠? 즉 리눅스용 파일을 윈도우용 파일로 변환하겠다는 말입니다. 같은 방식을 적용하면 아래와 같이 되겠네요.

UNIX => DOS
예제) sed -i -e 's/$/\r/' test.sh


아무튼 리눅스에서 파일 형식을 상호간에 변경하는 것은 위 sed 명령어로 간단히 처리할 수 있는데, 근본적으로 이 오류가 발생하지 않도록 애초에 윈도우에서 리눅스용 스크립트를 작성할 때 미리 처리를 잘 해주면 되겠죠?

많은 텍스트 에디터가 그 기능을 지원합니다. 예를 들어 에디트 플러스의 경우 문서 - 파일 형식 - 파일 형식 변경으로 들어가시면 됩니다.


울트라 에디트의 경우 더 편리합니다. 다른 이름으로 저장할 때 줄 종료 형식을 지정할 수 있거든요.


또는 메뉴에서 파일 - 변환 - DOS -> UNIX를 선택하셔도 됩니다.



별거 아닌 내용을 가지고 길게 설명드린 것 같은데, 아무튼 윈도우와 리눅스 사이를 왔다 갔다 하시는 분들은 텍스트파일의 개행 처리 때문에 문제가 발생할 수 있다는 점을 항상 유념해두고 작업하시길 바랍니다. 이상입니다.

  1. 2011.12.24 02:57

    비밀댓글입니다

  2. hee
    2011.12.24 08:05 신고

    nix 환경이라면 이런 프로그램도 있습니다.
    u2d : unix -> dos
    d2u : dos -> unix

  3. BlogIcon 앗싸리30
    2011.12.24 08:08 신고

    ^M을 삭제하기 위해서 vi command mode에서

    :%S/^M//g

    라고 명령을 주시면 모든 ^M이 사라집니다.

    단 ^M을 입력하시려면 ^와 M을 각각 누르시면 안되고 ctrl + v + M을 누르시면 ^M이 한번에 입력되도록 하시면 됩니다.

    유닉스 작업환경에서는 자주 쓰시게 될 겁니다.

  4. BlogIcon hongyang
    2011.12.24 10:39 신고

    윈도우에서는 utf-8에 bom을 줕이기도 하지요. 쓸데없이

  5. 지나가다
    2011.12.26 11:01 신고

    rhel 환경이라면
    $ unix2dos
    $ dos2unix
    도 한번 사용해보세요.

  6. 손님
    2011.12.27 14:33 신고

    저도 이 문제 때문에 한참 고생했었는데요..
    저의 경우에는 변환해줘야 하는 파일이 좀 많고,
    서버에서 작업후 다시 ftp로 전송하기 귀찮아
    EOL Converter 라는 프리웨어를 사용했습니다.
    Window, Mac, Unix 상호 변환이 가능해 상당히 자주 활용하게 됩니다.