如何在WSL中运行Bash脚本时修复"$'\r': command not found"错误?

我在尝试使用junyanz/pytorch-CycleGAN-and-pix2pix时,在WSL中遇到了错误。
我按照Windows 10上的PyTORCH安装步骤:带有屏幕截图的说明上的步骤,在Windows 10 x64上成功安装了所有内容,然后在GitHub桌面版中切换到Ubuntu for Windows 如何在Windows 10上安装和使用Linux Bash Shell
但是我在最新的步骤遇到了阻碍。
具体来说,当我试图在Windows中下载或训练模型时出现问题。例如,在Ubuntu Linux提示符中,我手动导航到适当的位置,并输入以下类似的命令(我还尝试了su模式)
bash pretrained_models/download_pix2pix_model.sh facades_label2photo

我遇到了一个立即出现的错误,总是相同的,类似于这些:
root@Azure:/mnt/c/Users/vincent/Downloads/vision/pytorch-CycleGAN-and-pix2pix# bash pretrained_models/download_pix2pix_model.sh facades_label2photo
pretrained_models/download_pix2pix_model.sh: line 2: $'\r': command not found
Note: available models are edges2shoes, sat2map, and facades_label2photo
pretrained_models/download_pix2pix_model.sh: line 4: $'\r': command not found
]pecified [facades_label2photo
pretrained_models/download_pix2pix_model.sh: line 6: $'\r': command not found
mkdir: cannot create directory ‘./checkpoints/facades_label2photo\r_pretrained\r’: No such file or directory
pretrained_models/download_pix2pix_model.sh: line 10: $'\r': command not found
WARNING: timestamping does nothing in combination with -O. See the manual
for details.

: No such file or directoryhphoto
pretrained_models/download_pix2pix_model.sh: line 12: $'\r': command not found
pretrained_models/download_pix2pix_model.sh: line 13: $'\r': command not found

有什么想法吗?

6我不知道你在做什么,但是$'\r': command not found强烈暗示问题可能是你使用了一个Windows文本编辑器,并且保存文件时采用了DOS风格的CRLF换行符 - 例如参考DOS vs. Unix Line Endings - steeldriver
1但我只是直接在Ubuntu命令提示符窗口中输入命令。根本不经过任何文本编辑器... - Vincent Thomas
1@VincentThomas 这是一个文本文件:pretrained_models/download_pix2pix_model.sh - wjandrea
1在这里尝试答案:如何将Windows换行符更改为Unix版本。如果有效,请告诉我们,我们将关闭您的问题作为重复问题。 - wjandrea
1@wjandrea 我认为这并不是真正的重复问题,如何将 Windows 的换行符改为 Unix 版本。在这里合理的解决方案是在 WSL 系统中运行 git clone,而不是额外努力尝试转换每个文件。如果目标是在 Ubuntu 上安装软件,没有必要先在其文件系统之外下载它。 - Eliah Kagan
@EliahKagan 是的,那是一个更好的解决方案。 - wjandrea
在VScode中,您只需在状态栏的右下角将CRLF更改为LF即可。 - peter.babic
1你也可以使用cat -v <文件名>命令在Unix命令行中查看行尾的"^M"。当你通过git设置修复后,你将不再看到"^M"。 - atom88
6个回答

在WSL内部:
sudo apt-get install dos2unix

然后,
dos2unix [file]

完整的文档:
man dos2unix

希望我的翻译能为您提供帮助,解决您的问题。

1这个方法很有效。我之前在使用VSCode时遇到了一个问题,我有一个执行一些rsync和ssh命令的shell脚本。按照Chaim的建议,我在WSL中安装了dos2unix,并且在Powershell中执行了一次wsl dos2unix deploy.sh,现在每次我输入wsl ./deploy.sh时都能完美运行!非常感谢。 - Dan Zuzevich
4另一种选择是使用 sed -i 's/\r$//' path/to/file 命令来去除文件中的 \r - Top-Master
3如果你遇到了 E: Unable to locate package dos2unix 的错误,请先运行 sudo apt-get update - Alexander Higgins
1@Chaim Eliyah,你为我节省了很多时间。 - captain-yossarian
通常情况下,使用sed命令应该是安全的,因为除了Windows操作系统外,其他操作系统都已经停止使用该字符。 - Chaim Eliyah
如果你遇到了“无法更改临时输出文件的权限”的问题,请使用“sudo dos2unix [文件名]”。 - captain-yossarian

如果你使用的是Windows系统,
1. 在NotePad++中打开你的shell文件。 2. 点击顶部菜单栏上的“编辑”,然后选择“EOL转换” --> “Unix(LF)”。 3. 现在将这个文件复制到你的Linux系统中,它应该可以正常运行而不会出现这些错误。

3工作得像魔法一样顺利! - Floating Sunfish
太完美了!在进行转换时,我注意到了一种奇怪的行为。之前,我的简单if语句在同一个文件夹中没有看到其他文件(它确实存在)。按照您的指示后,if语句在搜索我的第二个文件时返回了true - marcin2x4
使用查找和替换功能将\r替换为空白对我来说没有效果,但这似乎是一个一键完成的版本。 - McKay G

steeldriver是正确的,问题在于您的文件具有Windows行尾标记,而bash无法运行它们。 $'\r'是代表回车符(CR)的表示形式,它是传统DOS和Windows行尾标记(CR LF)的一部分,但在传统的Unix风格行尾标记(LF)中不存在。

正如你所说,你正在尝试在bash中运行脚本的命令,但请注意脚本实际上存储在你的Ubuntu(WSL)系统之外,在你的Windows下载目录中:

/mnt/c/Users/vincent/Downloads/vision/pytorch-CycleGAN-and-pix2pix

WSL路径以/mnt/c开头,其中c可以是任何Windows驱动器字母,这些路径访问的是Ubuntu系统之外的文件和目录。作为Windows路径来说,即:
C:\Users\vincent\Downloads\vision\pytorch-CycleGAN-and-pix2pix

在Windows系统中存储文件并不意味着它使用Windows风格而不是Unix风格的换行符。然而,如果你在Windows上使用Git下载文件,默认配置是使用Windows风格的换行符。

解决问题最简单的方法是从Ubuntu系统的提示符下下载你需要的文件。我建议你完全更新Ubuntu系统,然后在Ubuntu中安装git,以及提供了编译大多数软件所需的有用工具的build-essential。对于Python程序,你可能不需要build-essential;如果你愿意,可以省略它,但我怀疑你最终会需要它。

sudo apt update && sudo apt upgrade && sudo apt install git build-essential

然后使用cd命令进入您想要下载软件的目录。这应该是您Ubuntu系统中的一个目录。例如,它可以是您的Ubuntu主目录或其中的某个位置。一旦进入该目录,从GitHub克隆存储库。我是在我的主目录内创建的src目录中进行的。
cd ~/src
git clone https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix.git

当然,你很可能首先需要安装依赖项。为了做到这一点,只需遵循所有官方指示。在Ubuntu系统中完成所有这些步骤。

1你也可以使用 cat -v <文件名> 命令在你的 Unix 命令行中查看行尾的 "^M"。当你通过 Git 设置修复后,你将不再看到 "^M"。 - atom88

我在WSL环境中使用VS Code来编辑bash脚本。将设置从右下角的"CRLF"更改为"LF",这对我解决了问题。

VSCode window


我遇到了这个问题,解决方法是配置git以Linux换行方式检出特定文件。
你可以在git根目录下添加一个名为.gitattributes的文件,用于配置git的特定属性(查看完整文档)。
添加以下内容:
# Convert to LF line endings on checkout.
*.sh text eol=lf

配置git使其在Windows机器上检出.sh文件时使用LF行结束符。

你也可以使用cat -v <文件名>命令在Unix命令行中查看行尾的"^M"。当你通过git设置修复后,你将不再看到"^M"。 - atom88

如果你手头有vim,它会迅速帮你解决问题。
vim $filename +"set ff=unix" +wq