
놀랍게도 윈도우와 유닉스 계열 운영체제는 텍스트 파일 내 줄바꿈을 저장하는 방식이 다릅니다. 두 방식에 대해 알아보겠습니다.
우선 윈도우는 줄바꿈을 \r, \n 2개의 문자로 저장합니다. 이때 \r을 Carriage Return, \n을 Line Feed로도 부르는데, 약칭을 따서 CRLF 저장 방식이라고도 합니다.
Carriage Return으로 커서를 줄 맨 앞으로 이동한 뒤, Line Feed는 커서를 한 줄 아래로 내립니다. CR과 LF는 16진수로 각각 0D, 0A인데 우측 16진수 에디터에서 0D, 0A가 저장되었음을 확인할 수 있습니다.
굳이 왜 줄바꿈을 두 문자로 나눴는지가 궁금할 수도 있는데, 사실 타자기의 유산입니다. 옛날 타자기로 줄바꿈을 할땐 실제로 레버를 왼쪽으로 민 뒤, 종이를 한 줄 위로 올려야 했습니다. 이런 잔재가 남은 것이라 생각하면 됩니다.
MacOS나 Linux에서는 Carriage Return 없이 Line Feed 문자로만 줄바꿈을 하는, LF 방식을 사용합니다. Line Feed 문자열만으로도 커서를 맨 앞으로 이동하고, 한 줄을 내리는 동작이 한 번에 이루어집니다. 우측 16진수 에디터에서도 0A만 저장됐음을 확인할 수 있습니다.
실제로 운영체제 간 줄바꿈 표준이 다르면 데이터를 주고받는 과정에서 호환성 문제가 생길 수 있습니다. 그래서 HTTP/1.1의 경우 줄바꿈 표준으로 CRLF를 정했습니다. 그렇기 때문에 직접 헤더를 보낼 때는, \r\n으로 줄바꿈을 해야 합니다.
이제 CRLF와 LF의 호환성 문제가 발생할 수 있는 사례를 알아보겠습니다. driver.sh 파일을 실행하려고 bash shell에 ./driver.sh를 입력했는데, 분명히 존재하는 파일임에도 required file not found 오류가 떴습니다. 어찌 된 일일까요?
문제는 driver.sh 파일은 CRLF로 저장됐지만, 제가 명령어를 실행한 도커 컨테이너는 리눅스 기반이라 LF를 사용해서 발생했습니다.
driver.sh의 첫 줄은, 이 파일을 실행할 때 /bin/bash를 사용하라는 뜻입니다. 이때 CRLF로 저장되는 만큼, 실제로는 #!/bin/bash\r\n으로 저장이 됩니다. 하지만 LF에서는 \n만 줄바꿈으로 인식하는 만큼, 그 앞의 \r까지 경로로 인식을 하게 됩니다.
결국 있지도 않는 /bin/bash\r을 찾지 못해 오류가 발생합니다.
간단히 파일의 줄바꿈 방식을 CRLF에서 LF로 바꾸면 문제를 해결할 수 있습니다. 리눅스 패키지 dos2unix를 사용해서 변경할 수도 있고, 아니면 VS코드 상 에디터에서 변경을 한 뒤 저장을 하면 됩니다.

CRLF와 LF를 보면 마치 자존심 강한 두 천재가 싸우는 것 같다는 느낌이 들기도 합니다. 특히 협업 과정에서 줄바꿈 양식이 다르면 예상치 못한 오류가 발생할 수 있으니, 유념해 두는 게 좋겠죠?
<대 본>
오늘은 CRLF 및 LF 줄바꿈 방식의 차이를 공유해 보겠습니다.
윈도우는 줄바꿈에 Carriage Return로도 불리는
\r, 그리고 Line Feed로도 불리는\n를 사용하는 CRLF 방식을 채택했습니다. 이때\r은 커서를 줄 맨 앞으로,\n은 한 줄 아래로 이동시키는 문자입니다.옛날 타자기로 줄을 바꿀 땐 레버를 왼쪽으로 밀고 종이를 한 줄 올려야 했는데, CRLF가 이런 방식을 본뜬 것이라고 생각하심 됩니다.
반면 MacOS나 Linux는
\n만 사용하는 LF 방식을 채택했습니다. LF에선\n하나로 커서를 앞으로 보내고 줄도 내립니다.HTTP/1.1 같은 경우, 운영체제 간 호환성을 위해 줄바꿈 표준을 CRLF로 설정했습니다. 따라서 저희도
\r\n으로 줄바꿈을 해야 했었죠.특히 줄바꿈 문제 때문에 이번 과제 채점에 필요한 driver.sh 파일이 실행되지 않는 일도 있었습니다.
CRLF로 저장된 쉘 파일의 매 줄 끝엔
\r\n이 붙습니다. 특히 첫 줄의 #!로 시작하는 코드는,/bin/bash경로에서 파일을 실행하라는 뜻입니다. 하지만 리눅스에선 끝의\n만 줄바꿈으로 인식하기 때문에,/bin/bash\r이란 잘못된 경로를 찾게 됩니다.해결 방법은 간단합니다. 줄바꿈 방식을 CRLF에서 LF로 바꾸면 됩니다. 리눅스 dos2unix 명령어를 사용하거나, VS코드를 사용하면 쉽게 변환이 가능합니다.
CRLF와 LF를 보면 마치 자존심 강한 두 천재가 서로의 방식이 맞다고 우기고 있는 것 같기도 하네요. 이상 마치겠습니다.