¿Cómo hacer que este script funcione bajo el símbolo del sistema ?, ahora todos los números aleatorios son iguales
SET SOME[1]="AA"
SET SOME[2]="BB"
SET SOME[3]="CC"
SET SOME[4]="DD"
SET SOME[5]="EE"
FOR /L %%i IN (1,1,5) DO FOR /F %%j IN ('SET RND=%%RANDOM%%*5/32768+1') DO ECHO SOME[%%i] %%j
windows-7
command-line
batch
nerdwaller
fuente
fuente
Respuestas:
Wow, tienes muchos problemas con ese pequeño fragmento de código :-)
A su código publicado le falta la opción SET / A. Supongo que su código real lo tiene.
La razón por la que su código falla con un error de sintaxis es porque el comando dentro de la cláusula FOR IN () se ejecuta a través de un
cmd /C yourCommandHere
comando. Cuandocmd /C
se analiza el comando implícito , se trata=
como un delimitador de token a menos que se escape o se cite. Cualquier cadena consecutiva de delimitadores de token se convierte en una sola<space>
antes de que su comando se ejecute realmente en un nuevo hilo CMD utilizando la semántica de línea de comando. La lista de delimitadores de tokens es,
;
=
<space>
<non-breaking space>
y<tab>
.Citar el comando eliminará el error de sintaxis:
Como se escapará el
=
:Pero realmente no necesita asignar el número aleatorio a una variable. El comando FOR IN () se ejecuta dentro de un contexto de línea de comando, y SET / A imprimirá el valor calculado en stdout cuando se ejecute dentro de un contexto de línea de comando. Entonces, lo siguiente también elimina cualquier error de sintaxis con efectivamente los mismos resultados:
Aquí hay un método más simple para dar un resultado del 1 al 5 (mod aleatorio 5 + 1):
Pero dudo seriamente que cualquiera de las soluciones anteriores dé el resultado deseado.
Algo muy peculiar sucede con el valor de
%RANDOM%
. Su uso de%%RANDOM%%
correctamente hace que la expresión se evalúe en cada iteración. Pero por alguna razón, el número aleatorio es casi constante para cualquier ejecución dada. De vez en cuando, una de las iteraciones variará, pero para la mayoría de las ejecuciones, cada iteración obtiene un valor constante. Creo que debe tener algo que ver con el valor inicial del generador de números aleatorios. Quizás el generador de números aleatorios se inicia con un valor inicial cada vez que se inicia una sesión CMD, y el valor inicial solo cambia muy lentamente. Recuerde que la cláusula FOR IN () se ejecuta en una nueva sesión CMD.Aquí hay un programa de prueba que demuestra que
%%test%%
se está reevaluando adecuadamente cada iteración. También muestra cómo%%random%%
se mantiene casi constante dentro de una carrera.Aquí está la salida de 2 ejecuciones del código anterior. Observe cómo la primera ejecución tiene una variación en el número aleatorio. La segunda carrera tiene un valor aleatorio constante.
Realmente no hay razón para poner el cálculo de números aleatorios dentro de una cláusula FOR / F IN ('comando'). Todo es mucho más simple si usa SET / A con expansión retrasada directamente dentro de su bucle externo.
Creo que lo siguiente puede ser lo que estás buscando:
Aquí hay algunos resultados de muestra:
EDITAR
Aquí hay una mejor evidencia de que el aleatorizador para la sesión CMD se reinicia y la semilla cambia lentamente.
--SALIDA--
fuente
%%RANDOM%%
se está reevaluando correctamente. Con el fin de conseguir alrededor de los problemas, Reestructuré el código de una manera que no requiere expansión retardada.Dado que está expandiendo la
%RANDOM%
variable en unFOR
bucle, debe usar la expansión retardada.Esto produce 5 ecos del mismo número:
Esto produce 5 números "aleatorios":
Puede encontrar más información sobre la expansión retrasada ejecutando
fuente
En este caso lo necesitas
delayed expansion
.Esto es más rápido que
%%test%%
. Ejemplo de salida:Esto también funciona (más lento):
Pero lo siguiente no funciona:
.
fuente