Пакетный сценарий Windows 7 «Для» Команда Ошибка / Ошибка - PullRequest
4 голосов
/ 03 декабря 2011

Кажется, есть ошибка в командном файле Windows 7 для команды «for». Эта команда может пройти через каталог с исходным кодом и возвращать одно имя файла за раз. Но я обнаружил, что если моя команда изменяет файлы в этом исходном каталоге, например,

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

команда 'for' может вызывать команду do с одним и тем же именем файла более 1 раза. (Обратите внимание, что в целях иллюстрации проблемы «echo es> tmp_x2932.tmp» - это просто простая замена некоторой другой допустимой команды, например «sed», которая редактирует исходный файл.)

Например, каталог с 9 файлами

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

даст такой результат (testdir.bat - это имя используемого пакетного файла):

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.

файл D: \ build-release \ dump \ f4 вызывается дважды по ошибке.

Такое поведение не наблюдается в Windows XP. Есть ли способ исправить это в Windows 7 без изменения старых скриптов? Я знаю, что всегда могу использовать временный каталог для хранения всех промежуточных файлов вместо их изменения на месте, но мои старые скрипты в Windows XP просто делают это.

1 Ответ

4 голосов
/ 03 декабря 2011

Пока что я могу только предложить заменить цикл FOR /R на FOR /F, который использует вывод DIR /S:

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