윈도우에서 메모장으로 작성한 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를 선택하셔도 됩니다.



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