Con:
FILES = $(shell ls)
rientrato sotto in all
questo modo, è un comando di compilazione. Quindi questo si espande $(shell ls)
, quindi prova a eseguire il comando FILES ...
.
Se FILES
si suppone che sia una make
variabile, queste variabili devono essere assegnate al di fuori della porzione della ricetta, ad esempio:
FILES = $(shell ls)
all:
echo $(FILES)
Ovviamente, ciò significa che FILES
verrà impostato su "output da ls
" prima di eseguire qualsiasi comando che crea i file .tgz. (Anche se, come nota Kaz, la variabile viene nuovamente espansa ogni volta, quindi alla fine includerà i file .tgz; alcune varianti devono FILES := ...
evitarlo, per efficienza e / o correttezza. 1 )
Se FILES
si suppone che sia una variabile di shell, puoi impostarla ma devi farlo in shell-ese, senza spazi e tra virgolette:
all:
FILES="$(shell ls)"
Tuttavia, ogni riga viene eseguita da una shell separata, quindi questa variabile non sopravviverà alla riga successiva, quindi è necessario utilizzarla immediatamente:
FILES="$(shell ls)"; echo $$FILES
È tutto un po 'sciocco poiché la shell si espanderà *
(e altre espressioni glob di shell) per te in primo luogo, quindi puoi semplicemente:
echo *
come comando della shell.
Infine, come regola generale (non realmente applicabile a questo esempio): come fa notare l' esperanto nei commenti, l'utilizzo dell'output di ls
non è completamente affidabile (alcuni dettagli dipendono dai nomi dei file e talvolta anche dalla versione di ls
; alcune versioni ls
tentano di disinfettare l'output in alcuni casi). Quindi, come l0b0 e nota idelica , se stai usando GNU make puoi usare $(wildcard)
e $(subst ...)
per realizzare tutto al make
suo interno (evitando qualsiasi problema di "caratteri strani nel nome del file"). (Negli sh
script, inclusa la porzione della ricetta dei makefile, un altro metodo è quello find ... -print0 | xargs -0
di evitare di inciampare in spazi vuoti, nuove righe, caratteri di controllo e così via.)
1 La documentazione di GNU Make rileva inoltre che POSIX ha aggiunto ::=
assegnazioni nel 2012 . Non ho trovato un collegamento di riferimento rapido a un documento POSIX per questo, né so da vicino quali make
varianti supportano l' ::=
assegnazione, anche se GNU make lo fa oggi, con lo stesso significato di :=
, cioè, fare l'assegnazione in questo momento con espansione.
Nota che VAR := $(shell command args...)
può anche essere scritto VAR != command args...
in diverse make
varianti, incluse tutte le varianti GNU e BSD moderne per quanto ne so. Queste altre varianti non hanno $(shell)
quindi l'utilizzo VAR != command args...
è superiore sia per essere più brevi che per lavorare in più varianti.
ls
consed
e cut, 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?