Respuestas:
Lo siguiente lo hará si, como supongo por su uso de ./a.out
, está en una plataforma de tipo UNIX.
for number in 1 2 3 4 ; do \
./a.out $$number ; \
done
Prueba de la siguiente manera:
target:
for number in 1 2 3 4 ; do \
echo $$number ; \
done
produce:
1
2
3
4
Para rangos más grandes, use:
target:
number=1 ; while [[ $$number -le 10 ]] ; do \
echo $$number ; \
((number = number + 1)) ; \
done
Esto genera del 1 al 10 inclusive, solo cambie el while
condición de terminación de 10 a 1000 para un rango mucho mayor como se indica en su comentario.
Los bucles anidados se pueden hacer así:
target:
num1=1 ; while [[ $$num1 -le 4 ]] ; do \
num2=1 ; while [[ $$num2 -le 3 ]] ; do \
echo $$num1 $$num2 ; \
((num2 = num2 + 1)) ; \
done ; \
((num1 = num1 + 1)) ; \
done
productor:
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
4 1
4 2
4 3
seq
comando que genera una secuencia de números existe en la mayoría (¿todos?) De los sistemas Unix, por lo que puede escribir for number in ``seq 1 1000``; do echo $$number; done
(Ponga una sola tecla de retroceso a cada lado del comando seq, no dos, no sé cómo formatear esto correctamente usando la sintaxis de stackoverflow)
make
normalmente trata a cada línea como una cosa que se ejecuta en un subconjunto separado . Sin continuación, intentaría ejecutar una subshell con solo (por ejemplo) for number in 1 2 3 4 ; do
, sin el resto del bucle. Con él, se convierte efectivamente en una sola línea del formulario while something ; do something ; done
, que es una declaración completa. La $$
pregunta se responde aquí: stackoverflow.com/questions/26564825/… , con el código aparentemente extraído de esta misma respuesta :-)
Si está utilizando GNU make, podría intentar
NÚMEROS = 1 2 3 4 hazlo: $ (foreach var, $ (NÚMEROS),. / a.out $ (var);)
que generará y ejecutará
./a.out 1; ./a.out 2; ./a.out 3; ./a.out 4;
./a.out 1
. ./a.out 2
se ejecutará independientemente
La razón principal para usar make IMHO es la-j
bandera. make -j5
ejecutará 5 comandos de shell a la vez. Esto es bueno si tiene 4 CPU, por ejemplo, y una buena prueba de cualquier archivo MAKE.
Básicamente, quieres hacer ver algo como:
.PHONY: all
all: job1 job2 job3
.PHONY: job1
job1: ; ./a.out 1
.PHONY: job2
job2: ; ./a.out 2
.PHONY: job3
job3: ; ./a.out 3
Esto es -j
amigable (una buena señal). ¿Puedes ver la placa de la caldera? Podríamos escribir:
.PHONY: all job1 job2 job3
all: job1 job2 job3
job1 job2 job3: job%:
./a.out $*
para el mismo efecto (sí, esto es lo mismo que la formulación anterior en lo que respecta a la marca , solo un poco más compacto).
Un poco más de parametrización para que pueda especificar un límite en la línea de comandos (tedioso como make
que no tiene buenas macros aritméticas, por lo que haré trampa aquí y usaré $(shell ...)
)
LAST := 1000
NUMBERS := $(shell seq 1 ${LAST})
JOBS := $(addprefix job,${NUMBERS})
.PHONY: all ${JOBS}
all: ${JOBS} ; echo "$@ success"
${JOBS}: job%: ; ./a.out $*
Ejecutas esto make -j5 LAST=550
con un valor LAST
predeterminado de 1000.
.PHONY: all
, make buscará un archivo llamado all
. Si existe un archivo de este tipo, haga entonces compruebe el último tiempo de cambio de ese archivo, y el archivo MAKE casi seguramente no hará lo que desea. La .PHONY
declaración le dice a make que all
es un objetivo simbólico. Por lo tanto, Make considerará que el all
objetivo siempre está desactualizado. Perfecto. Ver el manual.
%
la regla está disponible como $*
en la receta.
Me doy cuenta de que la pregunta tiene varios años, pero esta publicación aún puede ser útil para alguien, ya que demuestra un enfoque que difiere del anterior y no depende de las operaciones de shell ni de la necesidad de que el desarrollador elimine un código rígido cadena de valores numéricos.
la macro incorporada $ (eval ....) es tu amiga. O puede ser al menos.
define ITERATE
$(eval ITERATE_COUNT :=)\
$(if $(filter ${1},0),,\
$(call ITERATE_DO,${1},${2})\
)
endef
define ITERATE_DO
$(if $(word ${1}, ${ITERATE_COUNT}),,\
$(eval ITERATE_COUNT+=.)\
$(info ${2} $(words ${ITERATE_COUNT}))\
$(call ITERATE_DO,${1},${2})\
)
endef
default:
$(call ITERATE,5,somecmd)
$(call ITERATE,0,nocmd)
$(info $(call ITERATE,8,someothercmd)
Ese es un ejemplo simplista. No se escalará bastante para valores grandes, funciona, pero como la cadena ITERATE_COUNT aumentará en 2 caracteres (espacio y punto) para cada iteración, a medida que avanza en los miles, lleva progresivamente más tiempo contar las palabras. Tal como está escrito, no maneja la iteración anidada (necesitaría una función de iteración y un contador separados para hacerlo). Esto es puramente gnu make, no es un requisito de shell (aunque obviamente el OP estaba buscando ejecutar un programa cada vez; aquí, solo estoy mostrando un mensaje). El if dentro de ITERATE está destinado a capturar el valor 0, porque $ (palabra ...) generará un error de lo contrario.
Tenga en cuenta que la cadena creciente para servir como contador se emplea porque el valor incorporado $ (palabras ...) puede proporcionar un recuento árabe, pero esa marca no admite operaciones matemáticas (no puede asignar 1 + 1 a algo y obtener 2, a menos que esté invocando algo desde el shell para lograrlo por usted, o utilizando una operación de macro igualmente complicada). Esto funciona muy bien para un contador INCREMENTAL, pero no tan bien para un contador DECREMENT.
No lo uso yo mismo, pero recientemente, tuve que escribir una función recursiva para evaluar las dependencias de la biblioteca en un entorno de compilación multibinario y multibiblioteca donde necesita saber para incorporar OTRAS bibliotecas cuando incluye alguna biblioteca que en sí tiene otras dependencias (algunas de las cuales varían según los parámetros de compilación), y uso un método $ (eval) y contador similar al anterior (en mi caso, el contador se usa para garantizar que de alguna manera no entremos en un interminable bucle, y también como un diagnóstico para informar cuánta iteración fue necesaria).
Algo más que no vale nada, aunque no es significativo para el OP. Q: $ (eval ...) proporciona un método para eludir el aborrecimiento interno de make a las referencias circulares, lo cual es bueno y está bien aplicar cuando una variable es un tipo macro (inicializado con =), versus una asignación inmediata (inicializada con: =). Hay veces que desea poder usar una variable dentro de su propia asignación, y $ (eval ...) le permitirá hacerlo. Lo importante a tener en cuenta aquí es que, en el momento en que ejecuta la evaluación, la variable se resuelve y la parte que se resuelve ya no se trata como una macro. Si sabe lo que está haciendo y está tratando de usar una variable en el RHS de una asignación para sí mismo, esto es generalmente lo que quiere que suceda de todos modos.
SOMESTRING = foo
# will error. Comment out and re-run
SOMESTRING = pre-${SOMESTRING}
# works
$(eval SOMESTRING = pre${SOMESTRING}
default:
@echo ${SOMESTRING}
Feliz haciendo
Para soporte multiplataforma, haga que el separador de comandos (para ejecutar múltiples comandos en la misma línea) sea configurable.
Si está utilizando MinGW en una plataforma Windows, por ejemplo, el separador de comandos es &
:
NUMBERS = 1 2 3 4
CMDSEP = &
doit:
$(foreach number,$(NUMBERS),./a.out $(number) $(CMDSEP))
Esto ejecuta los comandos concatenados en una línea:
./a.out 1 & ./a.out 2 & ./a.out 3 & ./a.out 4 &
Como se mencionó en otra parte, en el uso de una plataforma * nix CMDSEP = ;
.
Esta no es realmente una respuesta pura a la pregunta, sino una forma inteligente de solucionar estos problemas:
en lugar de escribir un archivo complejo, simplemente delegue el control a, por ejemplo, un script bash como: makefile
foo : bar.cpp baz.h
bash script.sh
y script.sh se ve así:
for number in 1 2 3 4
do
./a.out $number
done
eval echo \$${$(var)}
; \ echo $$ var1; \ ((NUM = NUM + 1)); \ done all: set_var here SSA_CORE0_MAINEXEC es una variable de entorno que ya está configurada, así que quiero que ese valor se evalúe o imprima utilizando la variable var1. Lo intenté como se muestra arriba pero no funciona. por favor ayuda.
bash
y así usar las características. El bucle es una de las características por las cuales esto se puede demostrar.
Puede usarlo set -e
como prefijo para el ciclo for. Ejemplo:
all:
set -e; for a in 1 2 3; do /bin/false; echo $$a; done
make
saldrá inmediatamente con un código de salida <> 0
.
Aunque el kit de herramientas de la tabla GNUmake tiene un while
bucle verdadero (lo que sea que eso signifique en la programación GNUmake con sus dos o tres fases de ejecución), si lo que se necesita es una lista iterativa, hay una solución simple interval
. Por diversión, también convertimos los números a hexadecimal:
include gmtt/gmtt.mk
# generate a list of 20 numbers, starting at 3 with an increment of 5
NUMBER_LIST := $(call interval,3,20,5)
# convert the numbers in hexadecimal (0x0 as first operand forces arithmetic result to hex) and strip '0x'
NUMBER_LIST_IN_HEX := $(foreach n,$(NUMBER_LIST),$(call lstrip,$(call add,0x0,$(n)),0x))
# finally create the filenames with a simple patsubst
FILE_LIST := $(patsubst %,./a%.out,$(NUMBER_LIST_IN_HEX))
$(info $(FILE_LIST))
Salida:
./a3.out ./a8.out ./ad.out ./a12.out ./a17.out ./a1c.out ./a21.out ./a26.out ./a2b.out ./a30.out ./a35.out ./a3a.out ./a3f.out ./a44.out ./a49.out ./a4e.out ./a53.out ./a58.out ./a5d.out ./a62.out
#I have a bunch of files that follow the naming convention
#soxfile1 soxfile1.o soxfile1.sh soxfile1.ini soxfile1.txt soxfile1.err
#soxfile2 soxfile2.o soxfile2.sh soxfile2.ini soxfile2.txt soxfile2.err
#sox... .... ..... .... .... ....
#in the makefile, only select the soxfile1.. soxfile2... to install dir
#My GNU makefile solution follows:
tgt=/usr/local/bin/ #need to use sudo
tgt2=/backup/myapplication/ #regular backup
install:
for var in $$(ls -f sox* | grep -v '\.' ) ; \
do \
sudo cp -f $$var ${TGT} ; \
cp -f $$var ${TGT2} ; \
done
#The ls command selects all the soxfile* including the *.something
#The grep command rejects names with a dot in it, leaving
#My desired executable files in a list.