我正在使用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
做一些piplelining,或甚至为此创建一个别名,但它不会涵盖一个脚本包含另一个脚本的情况。
我到目前为止找到的唯一可接受的解决方案是将Git设置为以UNIX格式签出源文件。
答案 0 :(得分:5)
您可以在根文件夹中的repo中提交.gitattributes文件,以便在签出时自动告诉Git将LF行结尾应用于所有.sh文件,即使在Windows上也是如此。这样,您或其他开发人员就不必记住在您克隆repo的每台计算机上配置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
答案 1 :(得分:3)
对于某些脚本,解决方案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的设置。
答案 2 :(得分:2)
我想你可以写一个像
这样的剧本#!/bin/bash
#bash_run_unixified
#unixify and run in bash
dos2unix < "$1" | /bin/bash
并假设您使用适当的权限(sudo chmod o+r,o+x
)将其保存在/ urs / local / bin / bash_run_unixified中,那么您可以在脚本前加上
#!/usr/local/bin/bash_run_unixified
#This script has CRLFs in it
如果你不想要这些不寻常的shebang线,你可以
$ ln -s /usr/local/bin/{bash_run_unixified,bash}
然后使用
(正如Walter A.所说,将它与bash^M
链接起来可能是一个好主意)
#!/usr/bin/env bash
因为你的shebang行(/usr/local/bin/
通常比$PATH
更接近/bin
的开头,所以env命令应该选择链接到{{1}的bash
}})。
(提醒:我还没有测试过这些)
答案 3 :(得分:1)
我最好的解决方案是确保使用能够直接使用适当的eol风格保存的编辑器(如Notepad ++或Sublime Text)。
这样,我在boot2docker会话中不需要dos2unix
任何文件。
答案 4 :(得分:0)
Visual Studio 代码也擅长将行结尾更改为 linux 或 windows 文件结尾