Мне нужно сгенерировать случайную строку и сохранить ее в переменной с помощью Makefile.
Я написал
install:
LOCALSTORAGE_ACCESS_TOKEN = echo $RANDOM | md5sum | head -c 20; echo;
echo $(LOCALSTORAGE_ACCESS_TOKEN)
Когда я запускаю его с помощью make install
, я получаю
LOCALSTORAGE_ACCESS_TOKEN = echo ANDOM | md5sum | head -c 20; echo;
/bin/sh: 1: LOCALSTORAGE_ACCESS_TOKEN: not found
d41d8cd98f00b204e980
echo
Так
LOCALSTORAGE_ACCESS_TOKEN
.RANDOM
я тоже пробовал
LOCALSTORAGE_ACCESS_TOKEN = echo $$RANDOM | md5sum | head -c 20; echo;
echo $(LOCALSTORAGE_ACCESS_TOKEN)
с тем же результатом
LOCALSTORAGE_ACCESS_TOKEN = echo $RANDOM | md5sum | head -c 20; echo;
/bin/sh: 1: LOCALSTORAGE_ACCESS_TOKEN: not found
d41d8cd98f00b204e980
echo
Это должно работать:
install:
$(eval LOCALSTORAGE_ACCESS_TOKEN := $(shell /bin/bash -c 'echo $$RANDOM' | md5sum | head -c 20; echo))
echo $(LOCALSTORAGE_ACCESS_TOKEN)
$$RANDOM
для того, чтобы замаскировать знак $ в Makefile$(shell ...
, чтобы переменной был назначен вывод команды (вместо самого текста команды)$(eval ...
, потому что код находится внутри таргета, и вы не можете определить переменные в таргетах иначеКаждая строка рецепта представляет собой сценарий оболочки, запускаемый отдельной оболочкой. Ваша первая строка синтаксически неверна. Вы пытаетесь присвоить переменную make в рецепте, make работает иначе. Пытаться:
install:
LOCALSTORAGE_ACCESS_TOKEN=$$(echo $$RANDOM | md5sum | head -c 20); \
echo $$LOCALSTORAGE_ACCESS_TOKEN
LOCALSTORAGE_ACCESS_TOKEN
теперь является переменной оболочки, она назначается с использованием синтаксиса оболочки в первой строке рецепта, но по-прежнему определяется во второй строке из-за продолжения строки (конечный \
). Обратите внимание на использование $$
вместо $
, чтобы избежать первого расширения с помощью make.
Если вы хотите, чтобы LOCALSTORAGE_ACCESS_TOKEN
была переменной make, доступной во всех строках всех рецептов, просто назначьте ее как реальную переменную make и вне любого рецепта:
LOCALSTORAGE_ACCESS_TOKEN := $(shell echo $$RANDOM | md5sum | head -c 20)
install:
echo $(LOCALSTORAGE_ACCESS_TOKEN)
Спасибо. Это работает, но случайность вовсе не случайна. Каждый раз сгенерированная строка одинакова.
Здесь это работает как шарм. Вы точно скопировали-вставили (кроме начальных пробелов, которые вы должны заменить на табуляцию)?
Да, я копипастил. Кажется случайным, совсем не случайным...
А в командной строке? Что произойдет, если вы наберете echo $RANDOM
в командной строке?
Переменная оболочки RANDOM
не является стандартной POSIX. Он доступен в bash (и, возможно, в других оболочках), но не во всех оболочках. Таким образом, если для запуска рецептов используется оболочка sh
или dash
, это нормально, что результат всегда один и тот же (вероятно 68b329da9893e34099c7
), потому что echo $RANDOM
всегда возвращает только символ новой строки. Чтобы проверить это, попробуйте добавить SHELL := bash
в начале вашего Makefile.
Спасибо, теперь это работает. Можно ли сохранить переменную как «глобальную» переменную, доступную для каждой строки рецепта установки?
Не имеет отношения к вопросу, но благодаря вашему использованию $ RANDOM | md5sum похоже, вы пытаетесь получить уникальный идентификатор. Имейте в виду, что $RANDOM имеет очень ограниченный диапазон (32 КБ), поэтому вероятность получения дубликатов невелика. Чтобы сделать его более безопасным, вы можете, например. также добавьте текущую метку времени (echo $ RANDOM.
date +%s.%N
)