简体   繁体   中英

syntax error near unexpected token ' - bash

I have a written a sample script on my Mac

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

and this works fine by displaying Example

When I run this script on a RedHat machine, it says

syntax error near unexpected token '

I checked that bash is available using

cat /etc/shells

which bash shows /bin/bash 

Did anyone come across the same issue ?

Thanks in advance !

It could be a file encoding issue.

I have encountered file type encoding issues when working on files between different operating systems and editors - in my case particularly between Linux and Windows systems.

I suggest checking your file's encoding to make sure it is suitable for the target linux environment. I guess an encoding issue is less likely given you are using a MAC than if you had used a Windows text editor, however I think file encoding is still worth considering.

--- EDIT (Add an actual solution as recommended by @Potatoswatter)

To demonstrate how file type encoding could be this issue, I copy/pasted your example script into Notepad in Windows (I don't have access to a Mac), then copied it to a linux machine and ran it:

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

In this case, Notepad saved the file with carriage returns and linefeeds, causing the error shown above. The \\r indicates a carriage return (Linux systems terminate lines with linefeeds \\n only).

On the linux machine, you could test this theory by running the following to strip carriage returns from the file, if they are present:

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

Then try to run the new file sh ./newfile . If this works, the issue was carriage returns as hidden characters.

Note: This is not an exact replication of your environment (I don't have access to a Mac), however it seems likely to me that the issue is that an editor, somewhere, saved carriage returns into the file.

--- /EDIT

To elaborate a little, operating systems and editors can have different file encoding defaults. Typically, applications and editors will influence the filetype encoding used, for instance, I think Microsoft Notepad and Notepad++ default to Windows-1252. There may be newline differences to consider too (In Windows environments, a carriage return and linefeed is often used to terminate lines in files, whilst in Linux and OSX, only a Linefeed is usually used).

A similar question and answer that references file encoding is here: bad character showing up in bash script execution

try something like

$ sudo apt-get install dos2unix
$ dos2unix offendingfile

Easy way to convert example.sh file to UNIX if you are working in Windows is to use NotePad++ (Edit>EOL Conversion>UNIX/OSX Format)

You can also set the default EOL in notepad++ (Settings>Preferences>New Document/Default Directory>select Unix/OSX under the Format box)

Thanks @jdt for your answer.

Following that, and since I keep having this issue with carriage return, I wrote that small script. Only run carriage_return and you'll be prompted for the file to "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

}

I want to add to the answer above is how to check if it is carriage return issue in Unix like environment (I tested in MacOS)

1) Using cat

cat -e my_file_name

If you see the lines ended with ^M$ , then yes, it is the carriage return issue.

2) Find first line with carriage return character

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

3) Using vim

vim my_file_name

Then in vim, type

:set ff

If you see fileformat=dos , then the file is from a dos environment which contains a carriage return.

After finding out, you can use the above mentioned methods by other people to correct your file.

I had the same problem when i was working with armbian linux and Windows . i was trying to coppy my codes from windows to armbian and when i run it this Error Pops Up. My problem Solved this way : 1- try to Coppy your files from windows using WinSCP . 2- make sure that your file name does not have () characters

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM