Mit:
FILES = $(shell ls)
Darunter all
so eingerückt , ist es ein Build-Befehl. Dies wird also erweitert $(shell ls)
und versucht dann, den Befehl auszuführen FILES ...
.
Wenn FILES
es sich um eine make
Variable handeln soll, müssen diese Variablen außerhalb des Rezeptteils zugewiesen werden, z.
FILES = $(shell ls)
all:
echo $(FILES)
Dies bedeutet natürlich, dass vor dem Ausführen eines der Befehle, mit denen die .tgz-Dateien erstellt werden, die Option FILES
"Ausgabe von ls
" festgelegt wird . (Wie Kaz bemerkt, wird die Variable jedes Mal neu erweitert, so dass sie schließlich die .tgz-Dateien enthält. Einige Markenvarianten müssen dies aus Gründen der Effizienz und / oder Korrektheit vermeiden. 1 )FILES := ...
Wenn FILES
es sich um eine Shell-Variable handeln soll, können Sie sie festlegen, müssen sie jedoch in Shell-ese ohne Leerzeichen ausführen und in Anführungszeichen setzen:
all:
FILES="$(shell ls)"
Jede Zeile wird jedoch von einer separaten Shell ausgeführt, sodass diese Variable nicht bis zur nächsten Zeile überlebt. Sie müssen sie daher sofort verwenden:
FILES="$(shell ls)"; echo $$FILES
Dies ist alles ein bisschen albern, da die Shell *
(und andere Shell-Glob-Ausdrücke) in erster Linie für Sie erweitert wird, sodass Sie einfach:
echo *
als Ihr Shell-Befehl.
Schließlich als allgemeine Regel (für dieses Beispiel nicht wirklich anwendbar): Wie Esperanto in Kommentaren feststellt, ist die Verwendung der Ausgabe von ls
nicht vollständig zuverlässig (einige Details hängen von den Dateinamen und manchmal sogar von der Version ab ls
; einige Versionen ls
versuchen, die Ausgabe zu bereinigen in manchen Fällen). So wie l0b0 und idelic Note, wenn Sie GNU verwenden machen Sie verwenden können , $(wildcard)
und $(subst ...)
alles , was im Inneren zu erreichen make
selbst (alle „weird Zeichen in Dateinamen“ Probleme zu vermeiden). (In sh
Skripten, einschließlich des Rezeptteils von Makefiles, besteht eine andere Methode darin find ... -print0 | xargs -0
, das Stolpern über Leerzeichen, Zeilenumbrüche, Steuerzeichen usw. zu vermeiden.)
1 In der Dokumentation zu GNU Make wird weiter darauf hingewiesen, dass POSIX 2012 eine zusätzliche ::=
Zuweisung vorgenommen hat . Ich habe dafür weder einen Schnellreferenzlink zu einem POSIX-Dokument gefunden, noch weiß ich sofort, welche make
Varianten die ::=
Zuweisung unterstützen, obwohl GNU make dies heute mit der gleichen Bedeutung tut :=
, dh die Zuweisung jetzt mit Erweiterung.
Beachten Sie, dass VAR := $(shell command args...)
dies auch VAR != command args...
in mehreren make
Varianten geschrieben werden kann, einschließlich aller modernen GNU- und BSD-Varianten, soweit ich weiß. Diese anderen Varianten haben keine $(shell)
Verwendung, daher VAR != command args...
ist die Verwendung sowohl kürzer als auch in mehr Varianten überlegen .
ls
mitsed
und cut) verwenden und dann die Ergebnisse in rsync und anderen Befehlen verwenden. Muss ich den langen Befehl immer wieder wiederholen? Kann ich die Ergebnisse nicht in einer internen Make-Variablen speichern?FILE = $(shell ls *.c | sed -e "s^fun^bun^g")
make
kann das ohne die Shell tun :FILE = $(subst fun,bun,$(wildcard *.c))
.Zusätzlich zu Toreks Antwort: Eine Sache, die auffällt, ist, dass Sie eine träge ausgewertete Makrozuweisung verwenden.
Wenn Sie auf GNU Make sind, verwenden Sie die
:=
Zuweisung anstelle von=
. Diese Zuordnung bewirkt, dass die rechte Seite sofort erweitert und in der linken Variablen gespeichert wird.Wenn Sie die
=
Zuweisung verwenden, bedeutet dies, dass jedes einzelne Vorkommen von$(FILES)
die$(shell ...)
Syntax erweitert und somit den Shell-Befehl aufruft. Dies verlangsamt Ihren Make-Job oder hat sogar einige überraschende Konsequenzen.quelle
for x in $(FILES); do command $$x; done
. Beachten Sie die Verdoppelung,$$
die eine einzelne$
an die Shell weitergibt. Auch Schalenfragmente sind Einzeiler; Um mehrzeiligen Shell-Code zu schreiben, verwenden Sie die Backslash-Fortsetzung, die vonmake
selbst verarbeitet und in eine Zeile gefaltet wird. Dies bedeutet, dass Semikolons mit Shell-Befehlstrennung obligatorisch sind.