Pregunta ¿En qué punto `for` o` for / R` enumeran el directorio (árbol)?


El comando for se puede usar para enumerar un directorio y aplicar (a) ciertos comandos en cada elemento. Con el /R lo mismo se puede lograr para un árbol de directorios completo.

¿Qué sucede cuando el contenido del directorio (árbol) enumerado es cambiado por los comandos en el cuerpo de for ¿mando?

Supuesto que tenemos el directorio D:\data con el siguiente contenido:

file1.txt
file2.txt
file3.txt

El resultado de for %F in ("*.txt") do echo %F cuando se ejecuta en dicho directorio reflejará obviamente la lista anterior.

Sin embargo, ¿cuál es el resultado de la for bucle cuando un comando en el for ¿El cuerpo modifica el contenido del directorio? Por ejemplo, uno de los archivos en la lista se borra, digamos file3.txt, antes de que sea realmente iterado? O si se crea un nuevo archivo, como file4.txtantes de completar el ciclo

Cómo for /R comportarse en ese contexto? Supuesto que hay varios subdirectorios sub1, sub2, sub3, cada uno contiene la lista de archivos anterior; for /R está iterando a través de sub2, sub1 ya ha sido procesado, pero sub3 aún no; los contenidos de sub1 y sub3 se cambian en ese punto (cuando actualmente se camina sub2 como se mencionó); ¿Qué será enumerado entonces? Supongo, el cambio de contenido de sub1 no será reconocido, pero ¿qué pasa con sub3?

Por último, ¿hay una diferencia en el comportamiento de for o for /R cuando se ejecuta en el símbolo del sistema o desde un archivo por lotes? ¿Y hay diferencias en las diferentes versiones de Windows?

Nota:
Ver también mi pregunta similar acerca de forfiles mando.


6
2017-08-12 20:47


origen


Respuestas:


¡Esta es una excelente pregunta!

Vamos a concentrarnos en la llanura for comando por un momento Hay un error conocido relacionado con este comando cuando se usa para renombrar archivos. Por ejemplo:

set i=0
for %%a in (*.txt) do (
   set /A i+=1
   ren "%%a" !i!.txt
)

En este caso es frecuente que ciertos archivos cambien de nombre dos veces, e incluso tres veces en ciertos casos. El problema es que este comportamiento depende de una serie de factores que no están documentados, como la posición del primer archivo renombrado dentro de la lista de archivos originales y varios otros puntos. Del mismo modo, si un archivo se elimina antes de que sea procesado por el for, se muestra un mensaje de "Archivo no encontrado" generalmente emitido (aunque no TODAS LAS veces). Si se crea un nuevo archivo en el directorio después el for comenzó la ejecución, entonces puede o no ser procesado por for dependiendo (de nuevo) de una serie de factores. La forma habitual de evitar el problema con el cambio de nombre es forzar for comando para leer primero la lista completa de archivos y entonces procesar la lista:

for /F "delims=" %%a in ('dir /B *.txt') do (
   set /A i+=1
   ren "%%a" !i!.txt
)

De esta manera, no importa los cambios que se pueden hacer en los archivos en el disco: el for /F comando siempre procesará el original lista de archivos

Un problema similar ocurre con for /R comando, pero en este caso la posibilidad de problemas es mayor porque hay más directorios donde se pueden hacer cambios dinámicos. De nuevo: el comportamiento exacto depende de una serie de factores desconocidos y la forma de evitarlos es a través de for /F ... in ('dir /S /B'). Sin embargo, si eres De Verdad interesado en este punto, lo aliento a hacer una serie de pruebas sobre el tema (y publicar los resultados). ;)


6
2017-08-12 23:09