[Linux] RHEL 윈도우 개행문자(^M) 문제와 해결법

 

리눅스 환경에서 윈도우에서 작성된 파일을 옮겨 사용할 때, 예상치 못한 오류를 만나는 경우가 종종 있습니다. 특히 쉘 스크립트 파일을 실행할 때 다음과 같은 에러를 경험할 수 있습니다.

# ./helloworld.sh
-bash: ./helloworld.sh: /bin/bash^M: bad interpreter: No such file or directory

파일을 열어보면 정상적인 것처럼 보입니다.

# cat helloworld.sh
#!/bin/bash

echo "Hello World"

그러나 sh 명령어로 강제로 실행을 시도하면 또 다른 문제가 발생합니다.

# sh helloworld.sh
helloworld.sh: line 2: $'\\r': command not found
Hello World

이 문제의 원인은 바로 윈도우와 리눅스의 개행문자 차이입니다.

  • Windows: CRLF (\\r\\n)
  • Linux: LF (\\n)

윈도우에서 작성된 파일은 줄 끝마다 \\r(Carriage Return)이 추가되는데, 리눅스 쉘은 이를 인식하지 못하고 오류를 일으킵니다.


파일에 개행문자(^M)가 들어있는지 확인하는 방법

리눅스에서는 파일 끝에 붙어 있는 ^M과 같은 비가시성 문자를 기본 출력에서는 확인할 수 없습니다. 따라서 다음과 같은 방법을 통해 윈도우 스타일 개행문자(\\r\\n, CRLF)가 포함되어 있는지 확인할 수 있습니다.

1. vi -b 옵션 사용

vi 편집기의 -b(binary mode) 옵션을 이용하면, 바이너리 모드로 파일을 열어 숨겨진 제어 문자를 확인할 수 있습니다.

# vi -b <filename>

열어보면 줄 끝마다 ^M이 붙어 있는 것을 확인할 수 있습니다.

test^M
^M
Hello World^M
Good Morning!!^M

이 방법은 파일 전체를 눈으로 직접 확인하고 수정할 수 있다는 장점이 있습니다.


2. cat -v 명령어 사용

cat -v 명령어를 이용하면, 파일의 비가시성 문자를 눈에 보이는 형태로 출력할 수 있습니다.

# cat -v test.txt
test^M
^M
Hello World^M
Good Morning!!^M

출력 결과에 ^M이 보인다면, 해당 파일에는 윈도우 스타일의 개행문자(CRLF)가 포함되어 있다는 의미입니다. cat -v는 간단한 파일이라면 빠르게 검토할 때 유용한 방법입니다.


3. file 명령어 사용

파일의 형식과 특성을 분석할 때 많이 사용하는 file 명령어를 통해서도 개행문자 정보를 확인할 수 있습니다.

# file test.txt
test.txt: ASCII text, with CRLF, LF line terminators

이 결과에서 with CRLF, LF line terminators라는 메시지가 보인다면, 파일에 윈도우 스타일 개행문자(CRLF)가 섞여 있다는 의미입니다. 반대로 리눅스 포맷으로 작성된 파일은 다음과 같이 표시됩니다.

# file test2.txt
test2.txt: ASCII text

file 명령어는 파일을 직접 열어보지 않고도 빠르게 포맷 상태를 확인할 수 있기 때문에, 파일이 많거나 자동화 스크립트에 활용할 때 유용합니다.


해결방법: 리눅스 포맷으로 변환하기

이 문제를 해결하려면 파일의 포맷을 리눅스 형식으로 바꿔야 합니다. 다음과 같은 방법들이 있습니다.

1. dos2unix 명령어 사용

가장 많이 사용하는 방법은 dos2unix를 이용해 한 번에 변환하는 것입니다.

# yum install dos2unix     # 설치가 안 되어 있을 경우
# dos2unix <filename>

dos2unix를 사용하면 모든 CRLF를 LF로 변환해줍니다.

2. vi, vim에서 직접 ^M 제거

편집기에서 바로 고칠 수도 있습니다.

  1. -b 옵션을 추가하여 vi 또는 vim으로 파일을 엽니다.

    # vi -b <filename>
    
  2. 명령 모드에서 다음 명령어를 입력합니다.

    :%s/^M//g
    

    여기서 ^MCtrl + v 누른 후 m또는 엔터를 입력해야 합니다.

    (단순히 ^M을 입력하는 게 아닙니다.)

    근데 창이 꺼져서 ^M입력이 안되는 경우에는 아래 명령어로 대체가 가능합니다. \r을 입력할경우 vi편집기가 이걸 인식해서 ^M으로 치환해 줍니다.

    :%s/\\r//g 
    

이 방법은 dos2unix를 설치할 수 없는 환경에서 유용합니다.

3. tr 명령어로 개행문자 제거

test.txt 파일에서 ^M(Carriage Return) 문자 제거하고 덮어쓰기.

# tr -d '\\r' < test.txt > tmpfile && mv tmpfile test.txt

마치며

윈도우와 리눅스의 개행문자 차이는 단순해 보이지만 실제 운영 환경에서는 다양한 문제를 유발할 수 있습니다. 특히 쉘 스크립트처럼 인터프리터가 파일의 첫 줄부터 인식해야 하는 경우, 이런 차이는 치명적인 장애로 이어질 수 있습니다.

정리하면 아래와 같습니다.

  • 파일에 문제가 생기면 먼저 ^M이 있는지 확인
  • dos2unix, vi 편집기, tr 명령어를 통해 적절한 방법으로 정리

댓글

이 블로그의 인기 게시물

[Linux] RHEL Local YUM Repository 구성

[Linux Command] sudo command 설명

[Ansible Modules] Fetch module 설명 및 활용