我正在使用 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 解释器自动转换 到 并运行文件?
当然,我可以像这样进行一些管道操作
cat script.sh | tr -d "\r" | sh
,甚至为此创建一个别名,但它不会涵盖一个脚本包含另一个脚本的情况。
到目前为止我找到的唯一可接受的解决方案是设置 Git 以 UNIX 格式签出源文件。
您可以在根文件夹中的存储库中提交一个 .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
对于某些脚本,解决方案
ln -s /bin/bash /bin/bash^M
将会失败。"$@"
运行它们。
编辑: 我用以下 bash^M 脚本尝试过:
#!/bin/bash
PROG=$1
shift
dos2unix $PROG > /dev/null 2>&1
$PROG "$@"
当您的脚本包含其他带有点的脚本时,这将会失败,在这种情况下,您应该避免这种解决方法并采用 Unix 格式。
你说你可以以Unix格式结帐,或者你可以自行更改文件。
并提交到git中,将unix文件以unix格式存储在git中是一种改进。当你确实想在 Windows 下编辑它们时,请随后更改编辑器或 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
如果你不想要这种不寻常的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命令应该选择链接到bash
的bash_run_unixified
)。
(警告:我还没有测试过这些)
我拥有的最佳解决方案是确保使用能够以正确的 eol 样式直接保存的编辑器(如 Notepad++ 或 Sublime Text)。
dos2unix
boot2docker 会话中的任何文件。
Visual Studio 代码还擅长将行结尾更改为 linux 或 windows 文件结尾