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

标签 bash shell sh carriage-return

<分区>

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

if true
then
  true
fi 

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

  • myscript: line 4: syntax error near unexpected token `fi' ,就好像 then 不存在一样。
  • myscript: line 6: syntax error: unexpected end of file ,就好像 fi 不存在一样。
  • myscript:第 4 行:意外标记 `$'\r' 附近的语法错误 .. 什么?

为什么这会发生在这个特定的脚本中,而不是在我的命令行或我从中复制的脚本中?

最佳答案

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

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


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

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

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

如何删除它们?

将您的编辑器设置为使用 Unix 行结尾(也称为“行终止符”或“行尾字符”)保存文件,然后重新保存。

您还可以使用 dos2unix yourscriptcat yourscript | 从命令行中删除它们tr -d '\r' > 固定脚本

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

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

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

关于bash - 为什么 shell 脚本在其他地方运行相同的代码时会出现语法错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31886144/

相关文章:

linux - 我怎样才能在 Linux 中获取目录中每个文件的所有者?

bash - 检查文件名是否与 bash 中的模式匹配

bash - 如何在 Mercurial 的 "push creates new remote head"周围编写一个钩子(Hook)?

Windows Shell 上下文菜单选项

linux - Ubuntu Zsh(通过 Vagrant)没有找到 Zsh 或其功能

python - 如何在脚本执行期间询问时从 python 脚本或 shell 脚本输入密码

linux - 小 sh 脚本错误

java -/bin/sh : 1: touch not found

bash - 如何在每个 "exec"命令处执行 Docker 镜像的入口点?

bash - 无法获取 Web 服务器的 PID