EDITED - Seems i've not explained it properly and people doesn't see how it works. My fault. I'm going to try to explain it better.
The reason is the way the for command works internally.
When the line for var in (files)
is reached, the directory is checked to see if any files match and need to be processed.
Then, for
command (cmd really), issues a directory query to enumerate the files. This query returns only the first file in set. If there are any aditional files that match the file mask in for
command, a flag is set that indicates to the caller (cmd) that there are more files to be processed, but the list of the remaining files is not yet retrieved.
When execution of code inside for
reachs the end of an iteration, and there are files pending to be read, a query is sent to get the remaining of the list of files pending to be processed and that match the for
file selection.
System fills a buffer with the list of files remaining. If at that point the list of files is short enough to be full readed in buffer, the query will not be repeated. If the list of files is big enough to not fit in buffer, partial list is retrieved and when files in retrieved list are processed, the query will be sent again to get more files to process.
Number of files in buffer depends on length of filename. Shorter filenames, more files in buffer and less queries to filesystem.
This behaviour (retrieving remaining list of files at end of first file processing) is only done if the query for files returns that there are files pending. When one query does not return that flag, no more files are retrieved.
EXCEPTIONS
If working in NTFS, the files only get included in "requeries" if they are alphabetically greater than the last file that has been processed in for
command.
If working if FAT, the query will include all new file generated that match the for
command file selection independly of it name. And yes, it can get into an infinite loop. (In tests, the system buffer only retrieve one filename, and requery in each iteration). You can try
break > a.txt && cmd /v:on /c "for %f in (*.txt) do break > !random!.txt"
All my tests has been made on a windows 7 64bit, NTFS and FAT32 partition (this on a USB drive). No way to test other configurations. If anyone see a diferent behaviour, please comment.
For more information, ZwQueryDirectoryFile