неожиданный 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
SimMac
источник

Ответы:

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 ""строка. Удаление двух двойных кавычек, оставляя, sudo echoзаставляет это работать отлично.
Винзи
@vinzee почему бы вы когда - нибудь работать echoс sudo? Тем не менее, то, что вы описываете, не имеет особого смысла, должно быть, что-то еще происходит.
Тердон
Я делаю это sudo echoпотому, что скрипт понадобится sudoпозже в командах, но я хочу, чтобы пользователь вводил свой пароль на ранних этапах, чтобы скрипт больше не нуждался в его вводе в течение нескольких минут. Что касается ошибки, у меня была та же ошибка, что и здесь, но она была устранена путем удаления 2 двойных кавычек. Ничего другого не произошло ..
Vinzee
1
@vinzee, возможно, вы захотите прочитать. Как запустить команду 'sudo' внутри скрипта? , Что касается цитат, должно быть что-то еще. Возможно, у вас был непечатный символ после кавычек, которые были удалены с ними, например. Или, может быть, у вас было две одинарные кавычки, а затем двойной ( echo ''") или что-то в этом роде, но должно было быть что-то, так echo ""как все в порядке.
Тердон
Спасибо за ссылку, вы правы. Запуск sudo echoпоказался мне немного странным. И сегодня вечером я снова попробую установить Linux, и вернусь, чтобы прокомментировать результаты.
Винзее
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

По какой-то причине непревзойденный "inside {} не перехватывается парсером оболочки. Именно здесь парсер оболочки может быть улучшен.

Самый быстрый алгоритм, чтобы найти проблему, это удалить половину вашего кода снизу, если синтаксическая ошибка исчезнет, ​​то это в этой половине. Если синтаксическая ошибка все еще существует, проблема в верхней половине.

Если проблема в более поздней половине, отмените удаление. Повторите этот процесс. Вы можете сузить до меньшего размера, чтобы найти источник проблемы.

При удалении кода вы должны удалить целый раздел кода. Например вся функция.

Вы можете использовать bash -n scriptname или просто напрямую выполнить скрипт. Оба должны работать.

Кемин Чжоу
источник
1
«По какой - то причине, непревзойденные» внутри {} не захвачен анализатором оболочки «. Это просто потому , что синтаксический, это будет соответствовать, по линии 1508? Т.е. строка открыта на линии 500 закрыта по линии 1508, а потом еще строка открывается на 1508 , который никогда не закрывается.
philh
Я не исследовал поведение цитирования bash. Bash может иметь многострочную кавычку "line1 \ nline2". Я помню, что в оболочке вы используете многострочную кавычку с << ENDMARK. Возможно, теперь вы можете напрямую использовать двойные кавычки для цитирования нескольких строк. Эта функция делает отладку очень сложной.
Кемин Чжоу