在意外标记附近的语法错误' – bash

我在我的Mac上写了一个示例脚本

#!/bin/bash test() { echo "Example" } test exit 0 

这显示示例工作正常

当我在RedHat机器上运行这个脚本时,它说

语法错误附近的意外令牌'

我检查了可用的bash

 cat /etc/shells which bash shows /bin/bash 

有没有人遇到同样的问题?

提前致谢 !

Solutions Collecting From Web of "在意外标记附近的语法错误' – bash"

这可能是一个文件编码问题。

在不同的操作系统和编辑器之间处理文件时遇到了文件类型编码问题 – 特别是在Linux和Windows系统之间。

我建议检查你的文件的编码,以确保它适合于目标linux环境。 我想如果你使用的是一个编码问题,如果你使用的是Windows文本编辑器,那么编码问题的可能性就会降低,但是我认为文件编码仍然值得考虑。

—编辑(添加@Potatoswatter建议的实际解决方案)

为了演示文件类型编码是如何成为这个问题的,我将你的示例脚本复制/粘贴到Windows中的记事本(我没有访问Mac),然后将它复制到一台Linux机器上运行:

 jdt@cookielin01:~/windows> sh ./originalfile ./originalfile: line 2: syntax error near unexpected token `$'{\r'' '/originalfile: line 2: `test() { 

在这种情况下,记事本用回车符和换行符保存了文件,导致上面显示的错误。 \r表示一个回车(Linux系统仅终止使用换行的行\n )。

在linux机器上,你可以通过运行以下命令来测试这个理论,如果它们存在,就从文件中去掉回车符:

 cat originalfile | tr -d "\r" > newfile 

然后尝试运行新文件sh ./newfile 。 如果这样做,问题是回车作为隐藏的字符。

注意:这不是你的环境的确切复制(我没有Mac访问权限),但是我认为这个问题可能是编辑器在某个地方将回车保存到文件中。

— /编辑

稍微详细一点,操作系统和编辑器可以有不同的文件编码默认值。 通常,应用程序和编辑器会影响所使用的文件类型编码,例如,我认为Microsoft Notepad和Notepad ++默认为Windows-1252。 在Windows环境下,回车和换行通常用于终止文件中的行,而在Linux和OSX中,通常只使用换行。

引用文件编码的类似问题和答案在这里: 显示在bash脚本执行中的坏字符

尝试类似的东西

 $ sudo apt-get install dos2unix $ dos2unix offendingfile 

如果您在Windows中工作,将example.sh文件转换为UNIX简单方法是使用NotePad ++(编辑> EOL转换> UNIX / OSX格式)

您还可以在记事本++中设置默认的EOL(设置>首选项>新建文档/默认目录>在格式框下选择Unix / OSX)

感谢@jdt为您的答案。

之后呢,因为我一直有回车这个问题,所以我写了那个小脚本。 只运行carriage_return ,你会被提示输入文件“清理”。

https://gist.github.com/kartonnade/44e9842ed15cf21a3700

 alias carriage_return=remove_carriage_return remove_carriage_return(){ # cygwin throws error like : # syntax error near unexpected token `$'{\r'' # due to carriage return # this function runs the following # cat originalfile | tr -d "\r" > newfile read -p "File to clean ? " file_to_clean=$REPLY temp_file_to_clean=$file_to_clean'_' # file to clean => temporary clean file remove_carriage_return_one='cat '$file_to_clean' | tr -d "\r" > ' remove_carriage_return_one=$remove_carriage_return_one$temp_file_to_clean # temporary clean file => new clean file remove_carriage_return_two='cat '$temp_file_to_clean' | tr -d "\r" > ' remove_carriage_return_two=$remove_carriage_return_two$file_to_clean eval $remove_carriage_return_one eval $remove_carriage_return_two # remove temporary clean file eval 'rm '$temp_file_to_clean 

}