З:
FILES = $(shell ls)
відступивши внизу all
так, це команда збірки. Отже, це розширюється $(shell ls)
, а потім намагається запустити команду FILES ...
.
Якщо FILES
передбачається, що це make
змінна, ці змінні повинні бути призначені поза частиною рецепта, наприклад:
FILES = $(shell ls)
all:
echo $(FILES)
Звичайно, це означає, що перед запуском будь-якої з команд, що створюють файли .tgz , FILES
буде встановлено значення "output from ls
" . (Хоча, як зазначає Kaz, змінна щоразу повторно розширюється, тому врешті-решт вона включатиме файли .tgz; деякі варіанти make повинні уникати цього для ефективності та / або коректності. 1 )FILES := ...
Якщо FILES
передбачається, що це змінна оболонки, ви можете встановити її, але це потрібно робити в оболонці ese, без пробілів, і в цитатах:
all:
FILES="$(shell ls)"
Однак кожен рядок запускається окремою оболонкою, тому ця змінна не збережеться до наступного рядка, тому її потрібно негайно використовувати:
FILES="$(shell ls)"; echo $$FILES
Це все трохи безглуздо, оскільки оболонка розшириться *
(і інші вирази глобусів оболонки) для вас, в першу чергу, тому ви можете просто:
echo *
як ваша команда оболонки.
Нарешті, як загальне правило (насправді не застосовується до цього прикладу): як зазначає есперанто в коментарях, використання вихідних даних ls
не є повністю надійним (деякі деталі залежать від назв файлів, а іноді навіть версії ls
; деякі версії ls
спроби дезінфікувати вихідні дані В деяких випадках). Таким чином, як l0b0 та ідеальна примітка, якщо ви використовуєте GNU, ви можете використовувати $(wildcard)
і $(subst ...)
виконувати все, що знаходиться всередині make
себе (уникаючи будь-яких "дивних символів у назві файлу"). (У sh
сценаріях, включаючи частину рецептурних файлів, інший метод полягає у використанні, find ... -print0 | xargs -0
щоб уникнути спотикання пробілів, нових рядків, контрольних символів тощо).
1 Документація GNU Make також зазначає, що POSIX робить додаткове ::=
призначення в 2012 році . Я не знайшов для цього короткого посилання на документ POSIX, і я не знаю, які make
варіанти підтримують ::=
призначення, хоча GNU make робить сьогодні, з тим самим значенням, що :=
, наприклад, виконує призначення зараз із розширенням.
Зауважте, що VAR := $(shell command args...)
також можна писати VAR != command args...
у декількох make
варіантах, включаючи всі сучасні варіанти GNU та BSD, наскільки мені відомо. Ці інші варіанти не мають, $(shell)
тому використання VAR != command args...
перевершує як коротший, так і роботу в більшій кількості варіантів.
ls
ізsed
і вирізати), а потім використовувати результати в rsync та інших командах. Чи потрібно повторювати довгу команду знову і знову? Чи не можу я зберегти результати у внутрішній змінній Make?