Как использовать sed в Makefile
Я попытался поместить следующее в мой Makefile:
@if [ $(DEMO) -eq 0 ]; then \
cat sys.conf | sed -e "s#^public_demo[\s=].*$#public_demo=0#" >sys.conf.temp; \
else \
cat sys.conf | sed -e "s#^public_demo[\s=].*$#public_demo=1#" >sys.conf.temp; \
fi
но когда я запустил make, я получаю следующую ошибку:
sed: -e expression #1, char 30: unterminated `s' command
Если я запускаю точные строки, содержащие sed
в консоли, они ведут себя правильно.
Почему я получаю эту ошибку и как можно устранить проблему?
Ответы
Ответ 1
Это может быть знак $подстановки, который интерпретируется make как переменной. Попробуйте использовать два из них, например . * $$ # public_demo. Затем make расширяет это до единственного $.
EDIT: Это была только половина ответа. Как ответили cristis: другая часть состоит в том, что нужно использовать одинарные кавычки, чтобы предотвратить bash от расширения знака $.
Ответ 2
Я предлагаю вам использовать одинарные кавычки вместо двойных кавычек, $
может быть обработан как специальный char make перед запуском sed:
cat sys.conf | sed -e 's#^public_demo[\s=].*$#public_demo=0#' >sys.conf.temp;
Ответ 3
Версия make
на моей машине:
$ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-redhat-linux-gnu
И версия sed
:
$ sed --version
GNU sed version 4.2.1
Я должен добавить обратную косую черту для $
, чтобы sed не принимал ее как конец строки:
cat sys.conf | sed -e 's#^public_demo[\s=].*\$$#public_demo=0#' >sys.conf.temp
Ответ 4
Используйте что-то еще, чем #
для разделения частей.
Ответ 5
одна проблема, с которой я работал с sed в make файле, не отвечает текущими ответами, поэтому я объясню это здесь. Я заполнял переменные Bash, например: remote_owner=$$($(MAKE) remote.owner)
, а затем используя эти переменные в моей замене sed. проблема из-за запутанного способа настройки моих правил, remote_owner
мог бы сделать собственный вывод в нем, давая мне ошибку:
sed: -e expression #1, char 69: unknown option to `s'
make: *** [alter_table_local.sql] Error 1
например, добавив отладочные сообщения, я обнаружил, что local_owner установлен на:
make[1]: Entering directory `/home/jcomeau/rentacoder/jh'
jcomeau
ответ заключался в том, чтобы добавить параметр --silent
, чтобы сделать: remote_owner=$$($(MAKE) --silent remote.owner)
Ответ 6
Я пробовал двойной знак $$
, но он не работал в моей проблеме, возможно, $$$$
или $$$$$$$$
работал бы, потому что мой Makefile вызывает другие Makefile и т.д. Но я нашел лучшее решение:
Создайте файл оболочки replacer.sh
в той же папке, что и ваш Makefile, который выполняет команду sed
. Дайте ему исполняемый бит с помощью
chmod +x replacer.sh
Теперь вы можете вызвать этот файл в своем файле Makefile:
./replacer.sh