Bash – 无缝地运行带有CRLF行结尾的脚本

我正在使用VM(在我的情况下只是boot2docker)在Windows主机上运行docker容器。 为了方便起见,我的源文件是从主机文件系统映射的,所以文本文件默认使用Windows风格的CRLF行尾而不是Unix风格的LF结尾。

当我尝试从Docker容器中运行一些.sh文件时,我会得到一个错误

bash: ./script.sh: /bin/bash^M: bad interpreter: No such file or directory 

有没有办法如何告诉bash / sh解释器自动将\ r \ n转换为\ n并运行一个文件?

当然,我可以做一些像这样的脚本cat script.sh | tr -d "\r" | sh cat script.sh | tr -d "\r" | sh cat script.sh | tr -d "\r" | sh甚至为此创build一个别名,但是它不会涵盖一个脚本包含另一个脚本的情况。

我迄今为止唯一可以接受的解决scheme是将Git设置为以UNIX格式签出源文件。

对于某些脚本, ln -s /bin/bash /bin/bash^M解决方案将失败。
因此,创建一个脚本/ bin / bash ^ M将dos2unix他们得到的参数,并运行"$@"

编辑:我试了下面的bash ^ M脚本:

 #!/bin/bash PROG=$1 shift dos2unix $PROG > /dev/null 2>&1 $PROG "$@" 

当你的脚本包含带有点的其他脚本时,这将失败,在这种情况下,你应该避免这种解决方法,并转换为Unix格式。
你说你可以用Unix格式签出,或者你可以自己更改文件。
并承诺到git,这是一个unix文件以unix格式存储在git中的改进。 当你真的想在Windows下编辑它们时,改变编辑器或dos2unix的设置。

我最好的解决方案是确保使用编辑器(如记事本++或崇高文本)能够直接保存与适当的EOL风格。

这样,我不必在我的boot2docker会话中dos2unix任何文件。

我想你可以写一个脚本如

 #!/bin/bash #bash_run_unixified #unixify and run in bash dos2unix < "$1" | /bin/bash 

并假设你保存在/ urs / local / bin / bash_run_unixified与适当的权限( sudo chmod o+r,o+x ),那么你可以前缀脚本

 #!/usr/local/bin/bash_run_unixified #This script has CRLFs in it 

如果你不想要这种不寻常的形象,你可以

 $ ln -s /usr/local/bin/{bash_run_unixified,bash} 

然后使用(如沃尔特A.注意到,它可能是一个好主意,也链接到bash^M太)

 #!/usr/bin/env bash 

因为你的shebang行( /usr/local/bin/通常比你的$PATH开头更接近于/bin所以env命令应该选择连接到bash_run_unixifiedbash )。

(谨慎的话:我还没有测试过这个)

您可以在根文件夹的repo中提交一个.gitattributes文件,以便在检出时自动告诉Git将LF行结尾应用于所有.sh文件,即使在Windows上也是如此。 这样,您或其他开发人员就不必记得在克隆回购的每台机器上配置Git。

 # Set line endings to LF, even on Windows. Otherwise, execution within Docker fails. # See https://help.github.com/articles/dealing-with-line-endings/ *.sh text eol=lf