Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

shell - Why is an extra file being created in FOR loop of batch program?

I've written the following batch file to create multiple files using FOR loop:

@echo off  
cls  
FOR /L %%i IN (1 1 10) DO (  
    echo.> file%%i.txt  
    IF ERRORLEVEL 0 echo Successfully created file 'file%%i.txt'.  
)  
dir /b *.txt  
FOR %%i IN (*.txt) DO (  
    echo.> file%%i.txt
    IF ERRORLEVEL 0 echo Successfully created file 'file%%i.txt'.  
)

Here, 10 files (viz. file1.txt .... file10.txt) are created in the first FOR loop.
And in the second FOR loop I've used these files to frame the name of next new files. (viz.filefile1.txt.txt ... filefile10.txt.txt)

But, an extra file is being created : filefilefile1.txt.txt.txt
What logical issue is causing the creation of this extra file ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...