Vagrant中的Windows CRLF到Unix LF问题

时间:2015-02-21 21:00:37

标签: vagrant virtual-machine vagrantfile eol

我正致力于使用Vagrant配置一些虚拟机。情况如下:

主机:Windows 7(64位)

访客:Ubuntu 14.04(64位)

我遇到了将CRLF行结尾转换为LF的问题。这导致共享文件夹中的bash脚本在来宾计算机中失败(见下文)。

vagrant@vagrant-host:/vagrant/bin$ sudo bash build-ubuntu-14.04.1-c
make.sh
build-ubuntu-14.04.1-cmake.sh: line 5: $'\r': command not found
build-ubuntu-14.04.1-cmake.sh: line 19: $'\r': command not found
: invalid option04.1-cmake.sh: line 21: set: -
set: usage: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
build-ubuntu-14.04.1-cmake.sh: line 22: $'\r': command not found
build-ubuntu-14.04.1-cmake.sh: line 24: $'\r': command not found
build-ubuntu-14.04.1-cmake.sh: line 26: $'\r': command not found
build-ubuntu-14.04.1-cmake.sh: line 29: $'\r': command not found
build-ubuntu-14.04.1-cmake.sh: line 36: $'\r': command not found
build-ubuntu-14.04.1-cmake.sh: line 42: $'\r': command not found
build-ubuntu-14.04.1-cmake.sh: line 46: $'\r': command not found
build-ubuntu-14.04.1-cmake.sh: line 48: $'\r': command not found
build-ubuntu-14.04.1-cmake.sh: line 50: $'\r': command not found
build-ubuntu-14.04.1-cmake.sh: line 226: syntax error: unexpected end of file

在我的Vagrantfile中,我已将shell privisioner参数binary设置为false。

# Provision the VM
ubuntu.vm.provision "shell" do |s|
  # replace Windows line endings with Unix line endings
  s.binary = false

  s.inline = "sudo apt-get update;
              sudo bash vagrant/bin/build-ubuntu-14.04.1-cmake.sh"
end

根据Vagrant文​​档:

  

binary(boolean) - Vagrant自动用Unix行结尾替换Windows行结尾。如果这是真的,那么Vagrant就不会这样做。默认情况下,这是" false"。如果shell配置程序通过WinRM进行通信,则默认为" true"。

这里的问题是什么?我是否忽略了文档中的内容?


更新1 : 我试图按照this Stack Overflow answer中的建议编辑我的本地Git设置,但没有运气。另外,我已将.gitattributes文件添加到项目的根目录中,并将以下内容添加到该文件中:

# detect all text files and automatically normalize them (convert CRLF to LF)
*       text=auto

我还阅读了Git提供的"Dealing with line endings"文件。当我提交到我的存储库时,CRLF会转换为LF,但是当我在Windows工作区中检出更改时,LF会转换为CRLF。这是我在Git工作流程中想要的确切行为。问题在于Vagrant。我设置的binary标记不会执行文档描述的方式。


更新2 : 更改s.binary = true解决了问题。但是,我认为文件中的措辞应该重新解决。文档说明"如果此[标志]为真,那么Vagrant 将不会执行此操作[将CRLF更改为LF]。"据我了解,如果设置了此标志,Vagrant将将CRLF更改为LF。但是,如果将此设置为true,则CRLF 将更改为LF。

3 个答案:

答案 0 :(得分:11)

你是对的,documentation about binary有误导性。我已经提议a pull-request,这已在文档页面上得到纠正。

现在它声明:

  

binary(布尔值) - Vagrant自动替换Windows行结尾   用Unix行结尾。 如果这是false,则Vagrant不会这样做   此即可。默认情况下,这是false。如果shell配置器是   通过WinRM进行通信,默认为true

所以要用Unix行结尾(CRLF)替换Windows行结尾(LF),你需要设置:

s.binary = true

替代解决方案包括:

  • 通过以下方式手动更改行结尾:

    • 使用dos2unix命令,
    • 使用ex命令,例如

      ex +'bufdo! %! tr -d \\r' -scxa *.sh
      
  • 将以下行添加到 Bashrc 文件中(例如~/.bashrc gist

    export SHELLOPTS
    set -o igncr
    

如果您使用Git对代码进行版本控制,则应该:

  • 通过将core.autocrlf选项设置为inputfalse,在OS X上配置Git以正确处理行结尾。

    如果你在Windows上安装了Git,最常见的错误是在安装过程中选择 Checkout Windows风格的选项,所以你应该重新安装它并选择:Checkout as-is和提交Unix样式的行结尾(core.autocrlf设置为input)或按原样结帐,按原样提交core.autocrlf设置为{{1 }})。

  • 考虑在您的存储库(.gitattributes)中创建git规范化文件,以确保没有CRLF行结束,无论是在结帐时还是在签入时,例如:

    false

    因此,人们在编辑您的配置脚本时,不会破坏行结尾。

  • 另请阅读:GitHub帮助中的Dealing with line endings

  • 相关:'\r': command not found - .bashrc / .bash_profile

答案 1 :(得分:7)

正如我在更新中所述,更改s.binary = true修复了问题。但是,我认为文件中的措辞应该重新解决。文档说明"如果这个[标志]为真,那么Vagrant将不会这样做[将CRLF改为LF]。"据我了解,如果设置了此标志,Vagrant将不将 CRLF更改为LF。但是,如果将此设置为true,则CRLF 将更改为LF。

答案 2 :(得分:0)

也许完成以上操作:

2020年9月,在Windows 10计算机上使用Vagrant 2.2.10,默认行为显然是尝试替换Windows行尾。但是,这意味着,如果您确实在Vagrantfile中使用Linux行结尾-将无法工作!

我遇到了一些稍有不同的错误,如

"Vagrantfile:1: syntax error, unexpected tIDENTIFIER, 
expecting end-of-input [+ reference to different places in the Vagrantfile]"

通过猜测,我终于有了将行尾从Linux LF更改为Windows CR + LF的想法,这一切都实现了。

TL; DR:在Windows上使用Vagrant,在您的Windows中使用Windows行尾(CR + LF) 流浪文件。