Вопрос или проблема
Я только что написал bash-скрипт и постоянно получаю эту ошибку EOF.
Вот мой скрипт (работает только на OS X):
#!/bin/bash
#ОПРЕДЕЛЕНИЯ НАЧАЛО
en_sq() {
echo -e "Включение умных кавычек..."
defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool true
status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "1" ]
then
echo -e "Успех! Умные кавычки теперь включены."
SUCCESS="TRUE"
else
echo -e "Извините, произошла ошибка. Попробуйте снова."
fi
}
di_sq() {
echo -e "Отключение умных кавычек..."
defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "0" ]
then
echo -e "Успех! Умные кавычки теперь отключены."
SUCCESS="TRUE"
else
echo -e "Извините, произошла ошибка. Попробуйте снова."
fi
}
en_sd() {
echo -e "Включение умных дефисов..."
defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool true
status=$(defaults read NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool)
if [ "$status" = "1" ]
then
echo -e "Успех! Умные дефисы теперь включены."
SUCCESS="TRUE"
else
echo -e "Извините, произошла ошибка. Попробуйте снова."
fi
}
di_sd() {
echo -e "Включение умных дефисов..."
defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
status=$(defaults read NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool)
if [ "$status" = "0" ]
then
echo -e "Успех! Умные дефисы теперь отключены."
SUCCESS="TRUE"
else
echo -e "Извините, произошла ошибка. Попробуйте снова."
fi
}
#ОПРЕДЕЛЕНИЯ КОНЕЦ
#---------------
#НАЧАЛО КОДА с параметрами
#Это завершится, если пользователь ввел параметры (например, ./sqd.sh 1 1)
if [ "$1" = "1" ]
then
en_sq
elif [ "$1" = "0" ]
then
di_sq
fi
if [ "$2" = "1" ]
then
en_sd
#выход 0, если оба, $1 и $2 правильно введены и обработаны.
exit 0
elif [ "$1" = "0" ]
then
di_sd
#выход 0, если оба, $1 и $2 правильно введены и обработаны.
exit 0
fi
#КОНЕЦ КОДА с параметрами
#---------------------------
#НАЧАЛО КОДА без параметров
#Это завершится, если пользователь не ввел два параметра
echo -e "\n\n\n\n\nИНФО: Вы можете использовать эту команду следующим образом: $0 x y, где x и y могут быть 0 для ложного или 1 для истинного."
echo -e "x отвечает за умные кавычки, y за умные дефисы."
sleep 1
echo -e " \n Чтение настроек...\n"
status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "1" ]
then
echo -e "Умные кавычки включены."
elif [ "$status" = "0" ]
then
echo -e "Умные кавычки отключены."
else
echo -e "Извините, произошла ошибка. Вы должны запустить это на OS X""
fi
status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "1" ]
then
echo -e "Умные дефисы включены."
elif [ "$status" = "0" ]
then
echo -e "Умные дефисы отключены."
else
echo -e "Извините, произошла ошибка. Вы должны запустить это на OS X!"
fi
sleep 3
echo -e "\n\n Теперь вы можете включить или отключить умные кавычки."
until [ "$SUCCESS" = "TRUE" ]
do
echo -e "Введите e для включения или d для отключения:"
read sq
if [ "$sq" = "e" ]
then
en_sq
elif [ "$sq" = "d" ]
then
di_sq
else
echo -e "\n\n ОШИБКА! Пожалуйста, введите e для включения или d для отключения!"
fi
done
SUCCESS="FALSE"
echo -e "\n\n Теперь вы можете включить или отключить умные дефисы."
until [ "$SUCCESS" = "TRUE" ]
do
echo -e "Введите e для включения или d для отключения:"
read sq
if [ "$sd" = "e" ]
then
en_sd
elif [ "$sd" = "d" ]
then
di_sd
else
echo -e "\n\n ОШИБКА! Пожалуйста, введите e для включения или d для отключения!"
fi
done
А вот моя ошибка:
./coding.sh: строка 144: неожиданный EOF при поиске соответствия `"
./coding.sh: строка 147: синтаксическая ошибка: неожиданный конец файла
Вы можете увидеть свою проблему, если просто посмотрите на свой вопрос. Обратите внимание, как подсветка синтаксиса испорчена после строки 95:
echo -e "Извините, произошла ошибка. Вы должны запустить это на OS X""
Как говорит сообщение об ошибке, у вас есть несоответствующая "
. Просто удалите лишнюю "
из приведенной выше строки, и у вас все будет в порядке:
echo -e "Извините, произошла ошибка. Вы должны запустить это на OS X"
Эту ошибку может быть трудно отследить в реальных ситуациях. Здесь я предоставляю одно решение для реальных ситуаций. Я использую свой скрипт в качестве примера.
Я обновил свой shell-скрипт. При его выполнении я получил следующее сообщение об ошибке:
/somepath/bin/myshellscript: строка 1508: неожиданный EOF при поиске соответствия `"
/somepath/bin/myshellscript: строка 1520: синтаксическая ошибка: неожиданный конец файла
строка 1508 elif [ "$project" ]; then
Это последняя строка, у которой есть пара двойных кавычек.
Обычно я проверяю свой shell-скрипт каждый раз, когда я вношу в него изменения. На этот раз я подождал один день и забыл, где я вносил изменения. Проблема возникла где-то перед этой строкой (1508). Проблема в том, что даже если я закомментировал строку 1508
#elif [ "$project" ]; then
исполнитель shell все же сказал, что строка 1508 имеет проблему.
Затем я сделал копию оригинального shell-скрипта. Удалив кучу кода снизу. Затем я проверил свой код с помощью следующей команды
bash -n mysbashscript
mybashscript: строка 515: неожиданный EOF при поиске соответствия `"
mybashscript: строка 561: синтаксическая ошибка: неожиданный конец файла
Теперь мой файл составляет 1/3 оригинального размера. Я сразу увидел проблему:
497 prepare_alignment() {
498 local projdir=${1:?"did не дать каталог проекта"}
499 local samp=${2:?"did не дать имя образца"}
500 local merged=${3:?"must give merged bam file name} # здесь проблема
По какой-то причине, несоответствующая "
внутри {}
не захватывается парсером shell. Это то место, где парсер shell можно было бы улучшить.
Самый быстрый алгоритм для поиска проблемы — удалить половину вашего кода снизу, если синтаксическая ошибка исчезнет, то она в этой половине. Если синтаксическая ошибка все еще существует, проблема в верхней половине.
Если проблема во второй половине, отмените удаление. Повторите этот процесс. Вы можете сузить до меньшего размера, чтобы найти источник проблемы.
При удалении кода вы должны удалить целый участок кода. Например, всю функцию.
Вы можете либо использовать bash -n имя_скрипта
, либо просто напрямую выполнить скрипт. Оба должны работать. (здесь имя_скрипта — это просто fooscript или barscript для иллюстративной цели, а не реальное имя скрипта и должно быть одно слово).
Еще один момент, который стоит учитывать, это то, что некоторые ключевые символы начинают блок, и двойные кавычки могут не быть проблемой. Я оборачиваю все свои переменные в bash в фигурные скобки, но если вы случайно используете квадратную скобку вместо фигурной, эта ошибка всплывает, и кавычки все frustringly выстраиваются в ряд. Используя процесс Кемина Чжоу, я смог найти эту опечатку. echo "Запуск $[report_name}" >> ${log}
выглядит очень похоже на echo "Запуск ${report_name}" >> ${log}
. И двойные кавычки НЕ являются проблемой, но сообщаются как таковые.
Я столкнулся с этой ошибкой из-за отсутствующей фигурной скобки…
docker tag "${FOO" "${BOO}"
Я знаю, что это старый вопрос, но я считаю, что утилита ShellCheck заслуживает упоминания. Вы можете скопировать/вставить свой скрипт на этом сайте для анализа или установить его на своем компьютере: https://github.com/koalaman/shellcheck
Shellcheck, вероятно, укажет местоположение проблемы напрямую. Когда я вставил скрипт OP в https://www.shellcheck.net веб-приложение, оно выдало кучу предупреждений и ошибок, но первые две были:
Строка 95:
echo -e "Извините, произошла ошибка. Вы должны запустить это на OS X""
^-- SC1009 (инфо): Упомянутая синтаксическая ошибка была в этой простой команде.
Строка 99:
if [ "$status" = "1" ]
^-- SC1078 (предупреждение): Вы забыли закрыть эту двойную кавычку?
Что сделало поиск ошибки очень простым.
Обратите внимание, что синтаксическая проверка редактора может не поймать некоторые тонкие ошибки кавычек, такие как @JesusIniesta’s пример:
docker tag "${FOO" "${BOO}"
Shellcheck указал на это напрямую (хотя и не упоминает, что проблема на самом деле заключается в незакрытом наборе фигурных скобок):
Строка 1:
docker tag "${FOO" "${BOO}"
^-- SC1009 (инфо): Упомянутая синтаксическая ошибка была в этом расширении параметров.
^-- SC1073 (ошибка): Не удалось разобрать эту двойную кавычку. Исправьте, чтобы разрешить больше проверок.
^-- SC1072 (ошибка): Ожидался конец двойной кавычки. Исправьте любые указанные проблемы и попробуйте снова.
Было бы намного полезнее, если бы bash выдал список строк с кавычками, охватывающими более одной строки. В подавляющем большинстве случаев первой инстанцией будет место, где проблема.
Ответ или решение
Ошибка "unexpected EOF while looking for matching `"’" в скрипте Bash часто указывает на несоответствующие кавычки или другие синтаксические проблемы в коде. Ниже я подробно рассмотрю типичные причины возникновения этой ошибки и предложу решения на основе анализа представленного вами скрипта.
Причины ошибки
-
Несоответствующие кавычки: Это наиболее распространенная причина упомянутой ошибки. Если в вашем коде есть не закрытые или лишние кавычки, Bash не сможет правильно интерпретировать скрипт.
-
Синтаксические ошибки: Не закрытые фигурные или квадратные скобки, а также неправильное использование операторов могут привести к возникновению этой ошибки.
-
Проблемы с интенцией: Неправильное форматирование кода, например, отсутствие отступов при вложении, может затруднить чтение и понимание структуры скрипта.
Анализ вашего скрипта
В вашем скрипте ошибка указывает на 144 строку, где присутствует не закрытая кавычка:
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"
После исправления этой строки вы, скорее всего, избежите ошибки "unexpected EOF".
Рекомендации по исправлению ошибок
-
Использование инструментов проверки: Используйте такой инструмент, как ShellCheck для анализа вашего скрипта. Он сможет указать на конкретные ошибки в коде и поможет вам быстро их исправить.
-
Пошаговая проверка: Если ошибка неочевидна, можно удалить части скрипта, чтобы локализовать проблему. Начните с нижней части скрипта — это позволит вам более эффективно выяснить, где могла произойти ошибка.
-
Консоль для дебага: Запускайте скрипт в интерактивном режиме с помощью
bash -n script_name
, чтобы увидеть предупреждения о синтаксических ошибках, не выполняя сам скрипт. -
Следите за отступами: Правильное форматирование кода улучшит его читабельность и уменьшит вероятность ошибок. Пользуйтесь редакторами кода, поддерживающими подсветку синтаксиса.
-
Тестирование функций: Разбивайте ваш код на более мелкие функции и тестируйте каждую по отдельности. Это упростит нахождение ошибок.
Заключение
Исправление ошибки "unexpected EOF while looking for matching `"’ требует внимательности при анализе кода, особенно в отношении кавычек и скобок. Применение предложенных рекомендаций поможет вам более эффективно отлаживать ваши скрипты Bash и избежать повторения подобных ошибок в будущем.