Con:
FILES = $(shell ls)
rientrato sotto all
del genere, si tratta di un comando di generazione. Quindi questo si espande $(shell ls)
, quindi tenta di eseguire il comando FILES ...
.
Se FILES
si suppone essere una variabile make
, queste variabili devono essere assegnati al di fuori della porzione ricetta, ad esempio:
FILES = $(shell ls)
all:
echo $(FILES)
Naturalmente, questo significa che FILES
verrà impostato su "output ls
" prima di eseguendo uno qualsiasi dei comandi che creano i file .tgz. (Anche se, come Kaz notes la variabile è ritesero ogni volta, così alla fine si includono i file .tgz, alcuni rendere varianti hanno FILES := ...
per evitare questo, per l'efficienza e/o correttezza .)
Se FILES
è dovrebbe essere una variabile di shell, è possibile impostare, ma è necessario farlo in guscio-ese, senza spazi, e citato:
all:
FILES="$(shell ls)"
Tuttavia, ogni linea è gestito da un guscio separato, in modo tale variabile non sopravviverà alla riga successiva, quindi è necessario utilizzarlo immediatamente:
FILES="$(shell ls)"; echo $$FILES
Questo è tutto un po 'sciocco in quanto il guscio si espanderà *
(e altre espressioni di shell glob) per voi in primo luogo, in modo da poter semplicemente:
echo *
come comando di shell.
Infine, come regola generale (in realtà non applicabile a questo esempio): come esperanto note nei commenti, utilizzando l'uscita dal ls
non è completamente affidabile (alcuni dettagli dipendono i nomi dei file e, talvolta, anche la versione del ls
, alcuni versioni di ls
tentano di disinfettare l'output in alcuni casi). Pertanto, come l0b0 e idelic note, se si utilizza GNU make è possibile utilizzare $(wildcard)
e $(subst ...)
per eseguire tutto all'interno di make
stesso (evitando problemi di "caratteri strani nel nome del file"). (In sh
script, tra la porzione di ricetta makefiles, un altro metodo è quello di utilizzare find ... -print0 | xargs -0
per evitare inciampare sbozzati, a capo, caratteri di controllo, ecc.)
The GNU Make documentation notes further that POSIX make added ::=
assignment in 2012.Non ho trovato un collegamento di riferimento rapido a un documento POSIX per questo, né so a maniere quali varianti di make
supportano l'assegnazione ::=
, sebbene GNU make lo faccia oggi, con lo stesso significato di :=
, cioè, esegui il compito adesso con espansione.
noti che VAR := $(shell command args...)
può anche essere scritto in diversi VAR != command args...
make
varianti, compresi tutti GNU moderno e BSD varianti per quanto ne so. Queste altre varianti non hanno $(shell)
quindi l'utilizzo di VAR != command args...
è superiore in entrambi i casi in cui sono più corti e che funzionano in più varianti.
Grazie. Voglio usare un comando elaborato ('ls' con' sed' e tagliare, per esempio) e poi usare i risultati in rsync e altri comandi. Devo ripetere il lungo comando più e più volte? Non posso memorizzare i risultati in una variabile Make interna? –
Gnu make potrebbe avere un modo per farlo, ma non l'ho mai usato, e tutti i makefile orribilmente complicati che usiamo usano solo variabili di shell e giganteschi comandi shell con un solo liner costruiti con "; \" alla fine di ogni riga come necessario. (non è possibile ottenere la codifica del codice per lavorare con la sequenza backslash qui, hmm) – torek
Inoltre, [invece di 'ls'] (http://mywiki.wooledge.org/ParsingLs) si vorrà usare il [' wildcard' make builtin] (https://www.gnu.org/software/make/manual/make.html#Wildcard-Function). – l0b0