为什么 shell 脚本在其他地方运行相同的代码时会出现语法错误?

Why is a shell script giving syntax errors when the same code works elsewhere?

我有一个从工作脚本复制的简单 shell 脚本。如果我将它复制粘贴到终端,它会起作用:

if true
then
  true
fi 

但是,当我 运行 使用 bash myscript 的脚本时,我会收到各种语法错误,就好像缺少某些关键字一样。

为什么在这个特定的脚本中会发生这种情况,但在我的命令行或我从中复制的脚本中却不会?

TL;DR:您的脚本具有 Windows 样式的 CRLF 行结尾,又名 \r\n.

通过删除回车 return 转换为 Unix 风格 \n


如何检查我的脚本是否有回车 returns?

它们在 cat -v yourscript 的输出中被检测为 ^M:

$ cat -v myscript
if true^M
then^M
  true^M
...

如何删除它们?

将您的编辑器设置为使用 Unix 行结尾保存文件,即 "line terminators" 或 "end-of-line characters",然后重新保存。

您也可以使用 dos2unix yourscriptcat yourscript | tr -d '\r' > fixedscript 从命令行删除它们。

为什么回车 returns 会导致语法错误?

回车 return 字符只是 bash 的另一个字符。 thenthen\r 不同,因此 bash 不将其识别为关键字并假定它是命令。然后它继续寻找 then 并失败

如果在 then 之后恰好有尾随 space,您会遇到与 fi 类似的问题。