Con:
FILES = $(shell ls)
sangrado debajo allasí, es un comando de compilación. Entonces esto se expande $(shell ls), luego intenta ejecutar el comando FILES ....
Si FILESse supone que es una makevariable, estas variables deben asignarse fuera de la parte de la receta, por ejemplo:
FILES = $(shell ls)
all:
echo $(FILES)
Por supuesto, eso significa que FILESse configurará como "salida desde ls" antes de ejecutar cualquiera de los comandos que crean los archivos .tgz. (Aunque, como señala Kaz, la variable se vuelve a expandir cada vez, por lo que eventualmente incluirá los archivos .tgz; algunas variantes de make tienen FILES := ...que evitar esto, por eficiencia y / o corrección. 1 )
Si FILESse supone que es una variable de shell, puede configurarlo, pero debe hacerlo en shell-ese, sin espacios y entre comillas:
all:
FILES="$(shell ls)"
Sin embargo, cada línea se ejecuta en un shell separado, por lo que esta variable no sobrevivirá a la siguiente línea, por lo que debe usarla inmediatamente:
FILES="$(shell ls)"; echo $$FILES
Todo esto es un poco tonto ya que el shell se expandirá *(y otras expresiones de shell glob) para usted en primer lugar, por lo que puede simplemente:
echo *
como su comando de shell.
Finalmente, como regla general (no realmente aplicable a este ejemplo): como se observa en esperanto en los comentarios, usar la salida de lsno es completamente confiable (algunos detalles dependen de los nombres de los archivos y, a veces, incluso de la versión de ls; algunas versiones de lsintento de desinfectar la salida en algunos casos). Por lo tanto, como nota l0b0 e idelic , si estás usando GNU make puedes usar $(wildcard)y $(subst ...)para lograr todo dentro de makesí mismo (evitando cualquier problema de "caracteres extraños en el nombre del archivo"). (En los shscripts, incluida la parte de recetas de los archivos MAKE, se utiliza otro método find ... -print0 | xargs -0para evitar tropezar con espacios en blanco, nuevas líneas, caracteres de control, etc.).
1 La documentación de GNU Make señala además que POSIX realiza una ::=asignación adicional en 2012 . No he encontrado un enlace de referencia rápida a un documento POSIX para esto, ni sé de antemano qué makevariantes admiten la ::=asignación, aunque GNU lo hace hoy, con el mismo significado que :=, es decir, hacer la asignación ahora mismo con expansión.
Tenga en cuenta que VAR := $(shell command args...)también se puede escribir VAR != command args...en varias makevariantes, incluidas todas las variantes modernas de GNU y BSD que yo sepa. Estas otras variantes no tienen, $(shell)por lo que su uso VAR != command args...es superior tanto por ser más cortas como por trabajar en más variantes.
lsconsedy cortar, por ejemplo) y luego usar los resultados en rsync y otros comandos. ¿Tengo que repetir el comando largo una y otra vez? ¿No puedo almacenar los resultados en una variable Make interna?FILE = $(shell ls *.c | sed -e "s^fun^bun^g")makepuede hacer que sin utilizar el shell:FILE = $(subst fun,bun,$(wildcard *.c)).Además, además de la respuesta de torek: una cosa que se destaca es que está utilizando una asignación de macro evaluada de forma perezosa.
Si está en GNU Make, use la
:=asignación en lugar de=. Esta asignación hace que el lado derecho se expanda inmediatamente y se almacene en la variable del lado izquierdo.Si usa la
=asignación, significa que cada aparición de$(FILES)expandirá la$(shell ...)sintaxis y, por lo tanto, invocará el comando de shell. Esto hará que su trabajo de creación se ejecute más lento o incluso tendrá algunas consecuencias sorprendentes.fuente
for x in $(FILES); do command $$x; done. Tenga en cuenta el doble$$que pasa un sencillo$al caparazón. Además, los fragmentos de concha son frases ingeniosas; para escribir código de shell de varias líneas, utiliza la continuación de la barra invertida que se procesa pormakesí misma y se dobla en una línea. Lo que significa que los puntos y comas de separación de comandos de shell son obligatorios.