为什么 shell 脚本在其他地方运行相同的代码时会出现语法错误?
Why is a shell script giving syntax errors when the same code works elsewhere?
我有一个从工作脚本复制的简单 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'
..什么?
为什么在这个特定的脚本中会发生这种情况,但在我的命令行或我从中复制的脚本中却不会?
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 yourscript
或 cat yourscript | tr -d '\r' > fixedscript
从命令行删除它们。
为什么回车 returns 会导致语法错误?
回车 return 字符只是 bash 的另一个字符。 then
与 then\r
不同,因此 bash 不将其识别为关键字并假定它是命令。然后它继续寻找 then
并失败
如果在 then
之后恰好有尾随 space,您会遇到与 fi
类似的问题。
我有一个从工作脚本复制的简单 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'
..什么?
为什么在这个特定的脚本中会发生这种情况,但在我的命令行或我从中复制的脚本中却不会?
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 yourscript
或 cat yourscript | tr -d '\r' > fixedscript
从命令行删除它们。
为什么回车 returns 会导致语法错误?
回车 return 字符只是 bash 的另一个字符。 then
与 then\r
不同,因此 bash 不将其识别为关键字并假定它是命令。然后它继续寻找 then
并失败
如果在 then
之后恰好有尾随 space,您会遇到与 fi
类似的问题。