Tất cả bài viết

CRLF so với LF: vì sao ký tự cuối dòng vẫn còn quan trọng

Việt Nam từng trải qua một cuộc phân mảnh tương tự nhưng ở tầng bảng mã: trước khi Unicode phổ biến, văn bản tiếng Việt được lưu bằng nhiều chuẩn cạnh tranh nhau như TCVN3, VNI, VPS — cùng một câu chữ hiển thị đúng trên máy này nhưng thành ký tự lỗi trên máy khác. Chuyện CRLF và LF là một phiên bản thu nhỏ, vẫn còn tồn tại, của đúng kiểu vấn đề "cùng nội dung, khác định dạng byte" đó.

Sự phân tách đến từ đâu

Unix và macOS dùng một ký tự duy nhất — LF (line feed, \n). Windows kế thừa từ các máy điện báo cũ một cặp ký tự — CRLF (carriage return + line feed, \r\n): một ký tự đưa con trỏ về đầu dòng, ký tự kia chuyển xuống một dòng — mô phỏng đúng nghĩa đen của máy đánh chữ.

Vì sao điều này vẫn quan trọng

  • Git. Nếu một tệp có CRLF lọt vào một repository mà các tệp khác dùng LF, git có thể hiển thị "toàn bộ tệp đã thay đổi" dù chỉ một dòng được chỉnh sửa — vì về mặt kỹ thuật, phần cuối của mọi dòng đã thay đổi.
  • Script shebang. Một script shell Unix được lưu với kết thúc dòng CRLF có thể không chạy được trên máy chủ, vì trình thông dịch thấy một ký tự \r thừa ở dòng đầu tiên.
  • So sánh chuỗi trong mã. Một dòng đọc từ tệp CRLF có thể không khớp khi so sánh với một chuỗi LF mong đợi, ngay cả khi văn bản hiển thị trông giống nhau.

Cách xử lý vấn đề này

Git có một cài đặt (core.autocrlf) tự động chuyển đổi ký tự xuống dòng khi checkout/commit, nhưng phụ thuộc vào cấu hình cục bộ của từng thành viên là không chắc chắn. Đáng tin cậy hơn là cố định kiểu xuống dòng trong tệp .gitattributes được commit cùng repository, để quy tắc áp dụng cho mọi người bất kể trình soạn thảo hay hệ điều hành nào.

Vì sao cần chuyển đổi thủ công

  • Sửa một tệp bị lọt vào repository với kiểu xuống dòng sai.
  • Chuẩn bị một script cho máy chủ Linux mà đã được chỉnh sửa trong trình soạn thảo Windows.
  • Chẩn đoán vì sao so sánh văn bản giữa hai tệp trông giống hệt nhau lại cho thấy sự khác biệt.

Kiểu xuống dòng hỗn hợp trong một tệp

Một tệp được chỉnh sửa qua nhiều trình soạn thảo hoặc trên các hệ điều hành khác nhau có thể chứa cả CRLF lẫn LF cùng lúc — một phần dòng theo kiểu này, phần khác theo kiểu kia. Đây là trường hợp khó xử lý nhất: chuyển đổi "sang LF" thoạt nhìn không thay đổi gì đối với các dòng vốn đã là LF, nhưng quan trọng là phải áp dụng phép chuyển đổi cho toàn bộ tệp, chứ không chỉ những dòng "đáng ngờ" nhìn thấy được, nếu không vấn đề sẽ vẫn còn ẩn giấu.

Dùng thử công cụ