32

I just wrote a bash script and always getting this EOF-Error.

So here is my script (only works on OS X):

#!/bin/bash

#DEFINITIONS BEGIN
en_sq() {
    echo -e "Enabling smart quotes..."
    defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool true
    status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
            if [ "$status" = "1" ]
                then
                    echo -e "Success! Smart quotes are now enabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
di_sq() {
    echo -e "Disabling smart quotes..."
    defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
    status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
            if [ "$status" = "0" ]
                then
                    echo -e "Success! Smart quotes are now disabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
en_sd() {
    echo -e "Enabling smart dashes..."
    defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool true
    status=$(defaults read NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool)
            if [ "$status" = "1" ]
                then
                    echo -e "Success! Smart dashes are now enabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
di_sd() {
    echo -e "Enabling smart dashes..."
    defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
    status=$(defaults read NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool)
            if [ "$status" = "0" ]
                then
                    echo -e "Success! Smart dashes are now disabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
#DEFINITIONS END
#---------------

#BEGIN OF CODE with properties
#This is only terminated if the user entered properties (eg ./sqd.sh 1 1)
if [ "$1" = "1" ]
    then
        en_sq
    elif [ "$1" = "0" ]
        then
            di_sq
fi

if [ "$2" = "1" ]
    then
        en_sd
        #exit 0 if both, $1 and $2 are correct entered and processed.
        exit 0
    elif [ "$1" = "0" ]
        then
            di_sd
            #exit 0 if both, $1 and $2 are correct entered and processed.
            exit 0
fi
#END OF CODE with properties
#---------------------------


#BEGIN OF CODE without properties
#This is terminated if the user didn't enter two properties
echo -e "\n\n\n\n\nINFO: You can use this command as following: $0 x y, while x and y can be either 0 for false or 1 for true."
echo -e "x is for the smart quotes, y for the smart dashes."
sleep 1
echo -e " \n Reading preferences...\n"
status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "1" ]
    then
        echo -e "Smart quotes are enabled."
    elif [ "$status" = "0" ]
    then
        echo -e "Smart quotes are disabled."

    else
        echo -e "Sorry, an error occured. You have to run this on OS X""
fi

status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "1" ]
    then
        echo -e "Smart dashes are enabled."
    elif [ "$status" = "0" ]
    then
        echo -e "Smart dashes are disabled."

    else
        echo -e "Sorry, an error occured. You have to run this on OS X!"
fi

sleep 3
echo -e "\n\n You can now enable or disable smart quotes."

until [ "$SUCCESS" = "TRUE" ]
do
echo -e "Enter e for enable or d for disable:"
read sq

if [ "$sq" = "e" ]
    then
        en_sq
    elif [ "$sq" = "d" ]
        then
            di_sq
    else
        echo -e "\n\n ERROR! Please enter e for enable or d for disable!"
fi
done
SUCCESS="FALSE"

echo -e "\n\n You can now enable or disable smart dashes."

until [ "$SUCCESS" = "TRUE" ]
do
echo -e "Enter e for enable or d for disable:"
read sq

if [ "$sd" = "e" ]
    then
        en_sd
    elif [ "$sd" = "d" ]
        then
            di_sd
    else
        echo -e "\n\n ERROR! Please enter e for enable or d for disable!"
fi
done

And here is my error:

./coding.sh: line 144: unexpected EOF while looking for matching `"'
./coding.sh: line 147: syntax error: unexpected end of file
30

You can see your problem if you just look at your question. Note how the syntax highlighting is screwed up after line 95:

echo -e "Sorry, an error occurred. You have to run this on OS X""

As the error message tells you, you have an unmatched ". Just remove the extra " from the line above and you should be fine:

echo -e "Sorry, an error occurred. You have to run this on OS X"
  • 1
    Strangely, I had the same problem and it was because I had a sudo echo "" line.. Removing the 2 double quotes, leaving sudo echo makes it work perfectly. – vinzee Sep 3 '18 at 21:04
  • @vinzee why would you ever run echo with sudo? That said, what you describe doesn't make much sense, there must have been something else going on. – terdon Sep 4 '18 at 8:02
  • I do sudo echo because the script will need sudo later in the commands but I want the user to enter his password early on, so that the script does not need his input anymore for a few minutes. And for the bug, I had the same error as seen here, but it was solved by removing the 2 double quotes. Nothing else happened.. – vinzee Sep 4 '18 at 8:04
  • 1
    @vinzee you might want to read How do I run a 'sudo' command inside a script?. As for the quotes, there must have been something else. Maybe you had a non-printing character after the quotes that was deleted with them, for instance. Or maybe you had two single quotes and then a double (echo ''") or something like that, but there had to be something since echo "" is fine. – terdon Sep 4 '18 at 8:22
  • Thanks for the link, you're right. Running sudo echo felt a bit weird.. And I'll try again on my linux install tonight and get back to comment here the results. – vinzee Sep 4 '18 at 8:29
1

This error can be hard to track in real situations. Here I provide one solution for real world situation. I will use my script as an example.

I updated my shell script. When executing it I got the following error message:

/somepath/bin/myshellscript: line 1508: unexpected EOF while looking for matching `"'
/somepath/bin/myshellscript: line 1520: syntax error: unexpected end of file

line 1508 elif [ "$project" ]; then

This is the last line that has a pair of double quotes.

Normally, I check my shell script every time I modify it. This time, I waited for one day and forgot where I had made modification. The problem happened anywhere before this line (1508). The problem is that even I commented out line 1508

#elif [ "$project" ]; then

the shell executioner still said line 1508 has trouble.

Next I made a copy of the original shell script. Deleting a whole bunch of code from the bottom. Then validate my code with the following command

bash -n mysbashscript

mybashscript: line 515: unexpected EOF while looking for matching `"'
mybashscript: line 561: syntax error: unexpected end of file

Now my file is 1/3 of the original size. I immediately saw the problem:

497 prepare_alignment() {
498     local projdir=${1:?"did not give project directory"}
499     local samp=${2:?"did not give sample name"}
500     local merged=${3:?"must give merged bam file name} # here is the problem

For some Reason, the unmatched " inside {} is not captured by the shell parser. This is where shell parser can be further improved.

The fastest algorithm to find the problem, is to delete half of your code from the bottom, if the syntax error goes away, then it is in this half. If the syntax error is still there, the the problem in in the upper half.

If problem in later half, undo delete. Repeat this process. You can narrow down to a smaller size to find the source of the problem.

When deleting code, you have to delete a whole section of code. For example the whole function.

You can either use bash -n scriptname or just directly execute the script. Both should work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.