我一直在和我的团队争论这个问题。在开发中,我们使用 Windows (CRLF),在服务器上我们使用 Linux (LF)。
如果 Linux 看到带有 CRLF 换行符的文件,是否有问题? Git 应该通过文件来处理这种情况.gitattributes
吗?
答案1
大多数情况下,当您将文件上传到服务器时,Linux 内核本身并不知道或关心行结尾。虽然作为穆鲁笔记CRLF 会搞砸舍邦。
然而,Linux 中有一个约定,即文本文件中的所有行都以单个 LF 结尾。许多工具会读取 CR 并将其视为任何其他工具常规字符(a,b,c,...)。这来自于文本文件的 POSIX 定义。
这能在某些语言中会导致问题,例如 shell 脚本(sh、bash、zsh、ksh...)。如果幸运的话,脚本将因虚假的额外参数引起的语法错误而失败。然而,在糟糕的情况下,这可能会渗透到文件的内容和文件名中。
对于仅设计用于在 linux / unix 下运行的工具和语言来说,这主要是一个问题。许多独立于平台的语言和工具会自动适应。所以你不太可能看到问题集成开发环境,或代码编辑器。
因此,为了试图结束你与同事的争论,Linux 中没有一个不存在 CRLF 行结尾的问题。 然而如果您将某些工具和语言留在其中,它们可能会令人窒息或发生奇怪的事情。
如果您正在编写要在 Linux / Unix 平台上运行的代码,那么通常更容易配置 git 来删除任何 CR 字符,留下 LF 行结尾。
答案2
一般来说,POSIX 将文本文件定义为每行以 LF 结尾的文件。因此,大多数 POSIX 实用程序将把 CRLF 视为一行,该行的末尾是一个以 CR 结尾的普通行,这被视为普通字符。
是否可以接受取决于您的需求。例如,wc
在计算单词数时可能不太关心 CR,而您可能会发现使用cut
或awk
选择某些字段可能最终会输出您不期望的 CR。正如其他人所指出的,大多数 POSIX 兼容 shell(甚至在 Windows 上)不喜欢 CR,并且会简单地拒绝处理语法错误
大多数文本编辑器(无论平台如何)都可以处理 CRLF 和 LF 结尾,有些还可以处理旧版 MacOS(即 MacOS 9 及之前版本)CR 行结尾。因此,您应该使用哪些行结尾主要取决于个人喜好、您所在的平台以及您正在使用的工具。
如果您使用 Git,最好的办法是告诉 Git 某些文件是文本文件(也就是说,它们应该转换行结尾)。这将导致 Git 在内部存储以 LF 结尾的文件,然后根据需要在签出时转换它们。您可以通过将类似的内容添加到.gitattributes
存储库中的文件中来完成此操作:
*.c text
*.h text
*.sh text eol=lf
*.ps1 text eol=crlf
*.jpg -text
这指定.c
文件.h
是文本,可以根据用户配置的设置以行结尾检出,并将以 LF 结尾写入存储库。对于.sh
文件,存储库和工作树都将具有 LF 结尾,对于.ps1
文件,存储库将具有 LF 结尾,而工作树将始终具有 CRLF 结尾,无论平台如何。 .jpg
文件根本不会进行任何行结束转换。
如果你不想指定每种文件,你可以简单地这样写:
* text=auto
Git 会尝试自动做正确的事情。
答案3
Linux 应用程序和应用程序库大多无缝处理所有类型的换行符,包括CRLF
(MS-DOS、Windows)或LF
(Unix、Linux)。您无需更改或指定任何内容。老的经典的苹果系统 (不是现代 MacOS X)使用CR
此类文件将无法正确处理(一切都将是一行)。
在某些情况下,您可能会遇到问题,CR
但您可以根据具体情况解决。
$ wc -l /tmp/test-*
2 /tmp/test-dos.txt
0 /tmp/test-mac.txt
2 /tmp/test-unix.txt
4 total
删除 CR 的工具有dos2unix
:
tr -d '\r' < input > output
或者sed
sed -i 's/\r$//g' file