Bash 脚本错误;执行轨迹中有'\r'字符

Bash script errors out; there are '\r' characters in the execution trace

我正在尝试制作一个小脚本,它或多或少会自动将我的项目目录与共享 git 存储库同步。但是,我似乎没有正确理解第一行。所以理论上这应该没问题:

#!/bin/bash
rsync -trnv /mnt/d/project/bundle/ /mnt/d/bundle/ --exclude=".git" --delete
cd /mnt/d/bundle/
git add .
read -p "" msg
git commit -m $msg
git push origin master
cd "${0%/*}"

据我所知,脚本失败了,因为它完全忽略了 rsync 命令的第二个选项。而且它找不到该目录,该目录是绝对路径并且存在。参见:

$ bash -x ptmrbundle-rsync.sh
+ rsync -trnv /mnt/d/bundle/ /mnt/d/project/bundle/ --exclude=.git $'--delete\r' rsync: --delete\#015: unknown option rsync error: syntax or usage error (code 1) at main.c(1572) [client=3.1.1]
+ cd $'/mnt/d/bundle/\r' : No such file or directory: cd: /mnt/d/bundle/

注意:正在为 windows 开发 linux 子系统。

因此,命令行在 shell 本身中工作得很好,但如果在 .sh 脚本中使用时完全失败。怎么了?

Windows 或 Linux 上的行尾不同。

正在考虑一个文件

Line A
Line B
Libe C

在Windows上实际上会像

Line A\r\n
Line B\r\n
Libe C\r\n

在 Linux 上会像

Line A\n
Line B\n
Libe C\n

如您所见,行尾的定义方式有所不同。

显然,您保存的文件带有 Windows 行尾 \r\n,因此 Linux 不会 "care" 关于 \r 它假定它是您正在编写的脚本...所以您实际上正在执行

#!/bin/bash\r
rsync -trnv /mnt/d/project/bundle/ /mnt/d/bundle/ --exclude=".git" --delete\r
cd /mnt/d/bundle/\r
git add .\r
read -p "" msg\r
git commit -m $msg\r
git push origin master\r
cd "${0%/*}"\r

这会导致各种问题。

要解决此问题,请在编辑器中打开文件并更改行结尾。

例如在记事本++中

  1. 打开文件
  2. 编辑 -> Eol 转换 -> Unix (LF)
  3. 保存文件