Неожиданный EOF при поиске соответствия «‘, но только при запуске из makefile?

#c #bash #shell #makefile

#c #bash #оболочка #makefile

Вопрос:

У моего сценария оболочки возникла проблема, однако он слишком длинный, чтобы публиковать его здесь. Вот ссылка на него: http://pastebin.com/jh9fHJ2e

У кого-нибудь есть идеи, почему я получаю эти две ошибки? Я вызываю его из makefile следующим образом:

 .PHONY: compile clean
compile:
    $(shell ./compile.sh)
clean:
    $(shell ./clean.sh)
  

Однако, если я запускаю его вручную ( `./compile.sh` ), я не получаю ошибку. Что я делаю не так? Я беспокоюсь, что кавычки поступают из выходных строк: make: Nothing to be done for 'default. из-за странного пропуска кавычек там, но как мне предотвратить это, если причиной этого является Make?

Надеюсь, это разумный, не повторяющийся вопрос. Это не то же самое, что и другие подобные, как я проверил. Я буду рад удалить, если это плохой вопрос, пожалуйста, просто дайте мне знать.

Комментарии:

1. Наоборот: вы точно определили проблему.

Ответ №1:

Вы не должны использовать $(shell ...) здесь. Функция оболочки похожа на обратные ссылки в сценарии оболочки: результатом выполнения является стандартный вывод вызванной команды. Если ваша команда печатает некоторый текст, он попытается быть выполнен как сценарий оболочки.

Рецепт уже запущен в оболочке, поэтому вам не нужна функция оболочки:

 .PHONY: compile clean
compile:
        ./compile.sh
clean:
        ./clean.sh
  

Хотел бы я понять, почему так много людей пытаются использовать функцию оболочки в подобных рецептах… Я чувствую, что там должно быть какое-то «вступление для создания», использующее очень плохие примеры.

В любом случае, как правило, вы бы не создавали отдельные сценарии оболочки: вы бы поместили команды compile и clean прямо в рецепт. Какой смысл иметь makefile, в котором вы вводите «make clean», когда все, что он делает, это запуск сценария оболочки, чтобы вы могли просто ввести «. /clean.sh » вместо этого и получить такое же поведение?

Комментарии:

1. Спасибо, это отлично работает! Я только что был принят на работу в качестве студента RA около месяца назад, и часть этого кода — настоящий беспорядок — я не знаю сценариев bash так много, как следовало бы, и поэтому я склонен пропускать такие простые вещи, как это. Большое спасибо. Через 9 минут, когда я смогу отметить ответ, я отмечу это.

2. PS — Зачем кому-то вообще пытаться это сделать? Вы абсолютно правы, что он уже запущен из оболочки… Я не могу придумать обоснованного обоснования этого. Может быть, у вас есть идея, почему.

3. Нет… понятия не имею. Жаль, что я этого не сделал, чтобы мы могли попытаться противодействовать этому 🙂

Ответ №2:

Синтаксис make $(shell ... ) запускает команду оболочки и в этот момент заменяет вывод команды оболочки в сценарий make. Итак, когда у вас есть правило, подобное

 compile:
        $(shell ./compile.sh)
  

он запустит скрипт compile.sh и примет выходные данные этого сценария оболочки в качестве действий (команд оболочки) для запуска для завершения compile цели. Поскольку похоже, что ваш compile.sh скрипт выполняет фактическую компиляцию, выводя сообщения о том, что он делает, когда make затем пытается запустить эти сообщения в виде команд оболочки, оболочка выдает барфы (выдает сообщения об ошибках).