Avec:
FILES = $(shell ls)
en retrait all
comme ça, c'est une commande de construction. Donc, cela se développe $(shell ls)
, puis essaie d'exécuter la commande FILES ...
.
Si FILES
est supposé être une make
variable, ces variables doivent être affectées en dehors de la partie recette, par exemple:
FILES = $(shell ls)
all:
echo $(FILES)
Bien sûr, cela signifie qu'il FILES
sera défini sur "sortie de ls
" avant d' exécuter l'une des commandes qui créent les fichiers .tgz. (Bien que, comme le note Kaz, la variable est ré-développée à chaque fois, elle inclura finalement les fichiers .tgz; certaines variantes doivent FILES := ...
éviter cela, pour plus d'efficacité et / ou d'exactitude. 1 )
Si FILES
est censé être une variable shell, vous pouvez le définir mais vous devez le faire en shell-ese, sans espaces, et entre guillemets:
all:
FILES="$(shell ls)"
Cependant, chaque ligne est exécutée par un shell séparé, donc cette variable ne survivra pas à la ligne suivante, vous devez donc l'utiliser immédiatement:
FILES="$(shell ls)"; echo $$FILES
Tout cela est un peu idiot car le shell se développera *
(et d'autres expressions shell glob) pour vous en premier lieu, vous pouvez donc simplement:
echo *
comme commande shell.
Enfin, en règle générale (pas vraiment applicable à cet exemple): comme le note l' espéranto dans les commentaires, l'utilisation de la sortie de ls
n'est pas complètement fiable (certains détails dépendent des noms de fichiers et parfois même de la version de ls
; certaines versions de ls
tentative de nettoyage de la sortie dans certains cas). Ainsi, comme le note l0b0 et idelic , si vous utilisez GNU make, vous pouvez utiliser $(wildcard)
et $(subst ...)
tout accomplir en make
lui-même (en évitant les problèmes de "caractères étranges dans le nom de fichier"). (Dans les sh
scripts, y compris la partie recette des makefiles, une autre méthode consiste à utiliser find ... -print0 | xargs -0
pour éviter de trébucher sur les blancs, les retours à la ligne, les caractères de contrôle, etc.)
1 La documentation GNU Make note en outre que POSIX a ajouté une ::=
affectation en 2012 . Je n'ai pas trouvé de lien de référence rapide vers un document POSIX pour cela, et je ne sais pas non plus quelles make
variantes prennent en charge l' ::=
affectation, bien que GNU le fasse aujourd'hui, avec le même sens que :=
, c'est-à-dire, faire l'affectation maintenant avec l'expansion.
Notez que cela VAR := $(shell command args...)
peut également être orthographié VAR != command args...
en plusieurs make
variantes, y compris toutes les variantes modernes GNU et BSD pour autant que je sache. Ces autres variantes n'ont pas, $(shell)
donc l'utilisation VAR != command args...
est supérieure à la fois en étant plus courte et en fonctionnant dans plusieurs variantes.
ls
avecsed
et couper, par exemple), puis utiliser les résultats dans rsync et d'autres commandes. Dois-je répéter la longue commande encore et encore? Puis-je stocker les résultats dans une variable Make interne?FILE = $(shell ls *.c | sed -e "s^fun^bun^g")
make
peut le faire sans utiliser le shell:FILE = $(subst fun,bun,$(wildcard *.c))
.De plus, en plus de la réponse de torek: une chose qui ressort est que vous utilisez une affectation de macro évaluée paresseusement.
Si vous êtes sur GNU Make, utilisez l'
:=
affectation au lieu de=
. Cette affectation entraîne l'expansion immédiate du côté droit et le stockage dans la variable de gauche.Si vous utilisez l'
=
affectation, cela signifie que chaque occurrence de$(FILES)
développera la$(shell ...)
syntaxe et invoquera ainsi la commande shell. Cela ralentira votre travail de ralentissement, voire aura des conséquences surprenantes.la source
for x in $(FILES); do command $$x; done
. Notez le doublé$$
qui passe un simple$
à la coque. En outre, les fragments de coquille sont à une seule ligne; pour écrire du code shell multiligne, vous utilisez la continuation de la barre oblique inverse qui est traitée parmake
elle-même et pliée en une seule ligne. Ce qui signifie que les points-virgules séparant les commandes shell sont obligatoires.