【问题标题】:Why is a shell script giving syntax errors when the same code works elsewhere? [duplicate]当相同的代码在其他地方工作时,为什么 shell 脚本会给出语法错误? [复制]
【发布时间】:2016-06-19 14:05:33
【问题描述】:

我有一个从工作脚本中复制的简单 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: line 4: syntax error near unexpected token `$'\r' .. 什么?

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

【问题讨论】:

  • 考虑将shellcheck.net 添加到您的自动化测试工作流程中。
  • 代码附近有Windows机器吗?非工作版本中是否有回车?其中一个错误使用$'\r',这表明这是问题所在。请参阅How to convert DOS/Windows newline (CRLF) to Unix newline (\n) in bash script? 以及许多其他相关问题。
  • @JonathanLeffler 是的,我捏造了这个问题并给出了社区答案,因为我永远无法找到一个一般性的问题来标记为重复。例如,您建议的内容是关于如何转换文件,而对于张贴者来说,为什么这完全相关并不明显。我已将这个添加到 bash 标签 wiki,但如果您找到更好的,我很乐意切换它。
  • 被问了很多次,你没能找到有用的信息真是令人惊讶。这里有一对12
  • @ThomasDickey 如果您更新 bash 标签 wiki 并提出任何您认为针对 CR 导致的重复数据删除语法错误的更好、通用、规范的常见问题解答,我将非常高兴删除此问题! (找到好的东西是很棘手的,你的 #2 就是这篇文章就证明了这一点。)

标签: bash shell sh carriage-return


【解决方案1】:

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' > fixedscript 从命令行删除它们。

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

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

如果then 后面恰好有一个尾随空格,fi 也会出现类似问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 2021-10-28
    • 1970-01-01
    • 2015-10-31
    相关资源
    最近更新 更多