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

时间:2014-01-03 03:20:01

标签: linux bash shell scripting

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

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

通过显示Example

可以正常工作

当我在RedHat机器上运行此脚本时,它会显示

  

意外标记'

附近的语法错误

我检查过bash是否可以使用

cat /etc/shells

which bash shows /bin/bash 

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

提前致谢!

6 个答案:

答案 0 :(得分:26)

这可能是文件编码问题。

在处理不同操作系统和编辑器之间的文件时遇到了文件类型编码问题 - 在我的情况下尤其是在Linux和Windows系统之间。

我建议检查文件的编码,以确保它适合目标linux环境。我想如果你使用的MAC比使用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中,通常只使用换行符)。

引用文件编码的类似问题和答案在这里:bad character showing up in bash script execution

答案 1 :(得分:4)

尝试类似

的内容
$ sudo apt-get install dos2unix
$ dos2unix offendingfile

答案 2 :(得分:4)

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

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

答案 3 :(得分:2)

感谢@jdt的回答。

之后,由于我一直有回车问题,我写了那个小脚本。只运行carriage_return,系统会提示您输入文件" clean"。

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

}

答案 4 :(得分:0)

我想添加到the answer above如何在Unix环境中检查它是否是回车问题(我在MacOS中测试过)

1)使用猫

cat -e my_file_name

如果您看到以^M$结尾的行,则为是,这是回车问题。

2)找回带回车符的第一行

grep -r $'\r' Grader.sh | head -1

3)使用vim

vim my_file_name

然后在vim中输入

:set ff

如果您看到fileformat=dos,那么该文件来自包含回车符的dos环境。

查明后,您可以使用上述其他人的方法来更正您的文件。

答案 5 :(得分:0)

在使用armbian linux和Windows时,我遇到了同样的问题。 我试图将我的代码从Windows复制到Armbian,当我运行它时,此错误弹出。我的问题是这样解决的: 1-尝试使用WinSCP从Windows复制文件。 2-确保您的文件名没有()字符