несподіваний EOF під час пошуку відповідності сценарію "" "bash


38

Я просто написав bash-скрипт і завжди отримував цю EOF-помилку.

Отже, ось мій сценарій (працює лише в 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

І ось моя помилка:

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

Відповіді:


32

Ви можете побачити свою проблему, якщо просто подивитись на своє запитання. Зверніть увагу, як підкреслюється синтаксис після рядка 95:

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

Як повідомляє повідомлення про помилку, у вас є неперевершене ". Просто видаліть зайве "з рядка вище, і вам буде добре:

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

1
Як не дивно, у мене була така ж проблема, і це було тому, що у мене був sudo echo ""рядок. Видалення 2-х подвійних лапок, виведення sudo echoзмушує її працювати ідеально.
vinzee

@vinzee чому б ви коли - небудь працювати echoз sudo? Однак, те, що ви описуєте, не має особливого сенсу, але, мабуть, щось інше відбувалося.
тердон

Я роблю це sudo echoтому, що сценарій знадобиться sudoпізніше в командах, але я хочу, щоб користувач вводив свій пароль на початку, щоб сценарій не потребував його введення протягом декількох хвилин. А для помилки у мене була та сама помилка, що і тут, але це було вирішено шляхом видалення 2 подвійних лапок. Нічого іншого не сталося ..
vinzee

1
@vinzee ви можете прочитати Як запустити команду 'sudo' всередині сценарію? . Щодо цитат, то, мабуть, було щось інше. Можливо, у вас з'явився недрукарський символ після цитат, видалених разом із ними. А може, у вас було дві одиничні лапки, а потім подвійний ( echo ''") чи щось подібне, але повинно бути щось, оскільки echo ""це добре.
тердон

Дякую за посилання, ви маєте рацію. Біг sudo echoвідчував себе трохи дивно .. І я спробую ще раз на своєму встановленні Linux сьогодні ввечері і повернусь, щоб прокоментувати тут результати.
vinzee

4

Цю помилку важко відстежити в реальних ситуаціях. Тут я пропоную одне рішення для реальної ситуації в світі. Я буду використовувати свій сценарій як приклад.

Я оновив свій скрипт оболонки. При його виконанні я отримав таке повідомлення про помилку:

/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

Це останній рядок, який має пару подвійних лапок.

Зазвичай я перевіряю свій скрипт оболонки щоразу, коли його змінюю. Цього разу я зачекав один день і забув, де я вніс модифікацію. Проблема сталася де-небудь до цього рядка (1508). Проблема полягає в тому, що я навіть прокоментував лінію 1508

#elif [ "$project" ]; then

Кат снаряда все ще сказав, що лінія 1508 має проблеми.

Далі я зробив копію оригінального сценарію оболонки. Видалення цілого ряду коду знизу. Потім підтвердіть мій код за допомогою наступної команди

bash -n mysbashscript

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

Тепер мій файл становить 1/3 початкового розміру. Я відразу побачив проблему:

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

З деяких причин незрівняний "всередині {} не фіксується аналізатором оболонки. Ось тут аналізатор оболонки може бути вдосконалений.

Найшвидший алгоритм пошуку проблеми полягає в тому, щоб видалити половину коду знизу, якщо помилка синтаксису зникла, то вона знаходиться в цій половині. Якщо помилка синтаксису все ще існує, проблема у верхній половині.

Якщо проблема пізніше, скасуйте видалення. Повторіть цей процес. Ви можете звузити до менших розмірів, щоб знайти джерело проблеми.

Видаляючи код, ви повинні видалити цілий розділ коду. Наприклад, вся функція.

Можна або використовувати ім'я скрипта bash -n, або просто безпосередньо виконати сценарій. Обоє повинні працювати.


1
«З якої - то причини, неперевершені» всередині {} НЕ захоплений аналізатором оболонки «. Це просто тому , що синтаксичний, це буде відповідати, по лінії 1508? Тобто рядок відкрита на лінії 500 закрита по лінії 1508, а потім ще струна відкрита в 1508 році, яка ніколи не закривається.
Філ

Я не досліджував котируючу поведінку баш. У Bash може бути багаторядкова цитата "line1 \ nline2" Я пам'ятаю, в оболонці ви робите багаторядкові цитати з << ENDMARK. Можливо, зараз ви можете безпосередньо використовувати подвійну цитату для цитування кількох рядків. Ця функція робить налагодження дійсно важким.
Kemin Zhou
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.