Windows 7 Batch Script 'For' Command Error/Bug

懵懂的女人 提交于 2019-12-18 08:45:28

问题


There seems to be a bug with the Windows 7 batch file 'for' command. This command can walk through a source directory and return one filename at a time. But I found that if my command modify the files in that source directory e.g.

for /R %1 %%s in (*.*) do call :do1file %%s
@goto :EOF

:do1file 
@echo es > tmp_x2932.tmp
move /y tmp_x2932.tmp  %1
@goto :EOF

the 'for' command could invoke the do command with the same file name more than 1 times. (Note that, for the purpose of illustrating the issue, the 'echo es > tmp_x2932.tmp' is just a simple replacement of some other legitimate command, like 'sed', that edit the original source file.)

For example, a directory with 9 files

D:\build-release\dump>dir /on
 Volume in drive D has no label.
 Volume Serial Number is 1972-268D

 Directory of D:\build-release\dump

12/03/2011  05:13 PM    <DIR>          .
12/03/2011  05:13 PM    <DIR>          ..
12/03/2011  05:40 PM                 5 f1
12/03/2011  05:40 PM                 5 f2
12/03/2011  05:40 PM                 5 f3
12/03/2011  05:40 PM                 5 f4
12/03/2011  05:40 PM                 5 f5
12/03/2011  05:40 PM                 5 f6
12/03/2011  05:40 PM                 5 f7
12/03/2011  05:40 PM                 5 f8
12/03/2011  05:40 PM                 5 f9
               9 File(s)             45 bytes
               2 Dir(s)  31,200,313,344 bytes free

will produce this result (testdir.bat is the batch file name used):

d:\test>testdir D:\build-release\dump
d:\test>for /R D:\build-release\dump %s in (*.*) do call :do1file %s
d:\test>call :do1file D:\build-release\dump\f4
d:\test>move /y tmp_x2932.tmp  D:\build-release\dump\f4
        1 file(s) moved.
d:\test>call :do1file D:\build-release\dump\f5
d:\test>move /y tmp_x2932.tmp  D:\build-release\dump\f5
        1 file(s) moved.
d:\test>call :do1file D:\build-release\dump\f6
d:\test>move /y tmp_x2932.tmp  D:\build-release\dump\f6
        1 file(s) moved.
d:\test>call :do1file D:\build-release\dump\f7
d:\test>move /y tmp_x2932.tmp  D:\build-release\dump\f7
        1 file(s) moved.
d:\test>call :do1file D:\build-release\dump\f8
d:\test>move /y tmp_x2932.tmp  D:\build-release\dump\f8
        1 file(s) moved.
d:\test>call :do1file D:\build-release\dump\f9
d:\test>move /y tmp_x2932.tmp  D:\build-release\dump\f9
        1 file(s) moved.
d:\test>call :do1file D:\build-release\dump\f1
d:\test>move /y tmp_x2932.tmp  D:\build-release\dump\f1
        1 file(s) moved.
d:\test>call :do1file D:\build-release\dump\f2
d:\test>move /y tmp_x2932.tmp  D:\build-release\dump\f2
        1 file(s) moved.
d:\test>call :do1file D:\build-release\dump\f3
d:\test>move /y tmp_x2932.tmp  D:\build-release\dump\f3
        1 file(s) moved.
d:\test>call :do1file D:\build-release\dump\f4
d:\test>move /y tmp_x2932.tmp  D:\build-release\dump\f4
        1 file(s) moved.

file D:\build-release\dump\f4 is called twice erroneously.

This behaviour is not observed in Windows XP. Is there any way to fix it in Windows 7 without changing the old scripts? I know I can always use a temporary directory to store all the intermediate files instead of modifying them in place, but my old scripts in Windows XP just do that.


回答1:


So far I can only suggest replacing the FOR /R loop with FOR /F that uses the output of DIR /S:

FOR /F "delims=" %%s IN ('DIR %1 /S /B') DO CALL :do1file %%s
…


来源:https://stackoverflow.com/questions/8366864/windows-7-batch-script-for-command-error-bug

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!