%date% дает другой результат в пакетном файле при запуске из запланированных задач в Server 2016
Пакетный файл запускает robocopy и создает файл журнала robocopyServer_%date%.txt
Когда пакетный файл запускается вручную, результатом является robocopyServer_yyyy-mm-dd.txt
Когда пакетный файл запускается из запланированных задач, результатом является robocopyServer_Tue (или каким-либо другим днем недели) - без расширения файла.
Этот пакетный файл работал безупречно под Server 2012R2 (вручную или по расписанию).
4 ответа
%date% или date /t
не всегда надежен, так как зависит от региона и пользовательских настроек. Вот как вы можете получить универсально действительную дату:
for /f %%# in ('wmic os get localdatetime^|findstr .') do if "%%#" neq "" set date=%%#
set date=%date:~,4%-%date:~4,2%-%date:~6,2%
echo %date%
Это отобразит текущую дату в формате гггг-мм-дд.
Формат строк переменных среды DATE и TIME зависит от настроек региона Windows, определенных для используемой учетной записи.
Независимую от региона строку даты / времени можно получить с помощью инструмента командной строки Windows Management Instrumentation WMIC.
Использование командной строки
wmic OS GET LocalDateTime /VALUE
Выходы UTF-16 Little Endian кодируются, например:
LocalDateTime=20170621095402.953000+120
Есть две пустые строки, затем строка с текущей датой / временем локали в формате YYYYMMDDHHmmSS.microsecond±UTC смещение в минутах и еще две пустые строки.
Эти данные могут быть использованы с кодом пакета, например так:
@echo off
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "FileNameDate=%%I"
set "FileNameDate=%FileNameDate:~0,4%-%FileNameDate:~4,2%-%FileNameDate:~6,2%"
echo %FileNameDate%
Для имен файлов и папок интерес представляет только строка даты / времени между знаком равенства и десятичной точкой, которая является причиной использования for /F
опции tokens=2 delims==.
чтобы получить только 20170621095402
присваивается переменной цикла I
чье значение присваивается рядом с переменной среды FileNameDate
,
Переменная среды FileNameDate
переформатируется с использованием подстановок строк, чтобы получить только строку даты в формате YYYY-MM-DD
который выводится для проверки, в результате чего 2017-06-21
,
Преимущество использования WMIC для получения локальной даты / времени заключается в независимости от настроек региона Windows. Недостатком является то, что выполнение команды занимает довольно много времени (от 1 до 2 секунд) по сравнению с использованием переменных окружения DATE и TIME, доступ к которым осуществляется за несколько микросекунд.
У команды FOR есть проблемы с синтаксическим анализом вывода Unicode правильно. Он интерпретирует последовательность байтов 0D 00 0A 00 0D 00 0A 00 в конце вывода WMIC из-за двух пустых строк как 0D 0D 0A, то есть как два возврата каретки и один перевод строки. Это приводит к интерпретации двух последних пустых строк в конце вывода WMIC как одной строки с одним возвратом каретки в качестве строки.
Это очень часто проблема в результате set "EnvironmentVariable=%%I"
это с %%I
расширение до возврата каретки при удалении переменной среды, уже определенной ранее с правильным значением.
Есть несколько решений, чтобы обойти эту ошибку синтаксического анализа Unicode команды FOR. Можно добавить & goto Label
выйти из цикла с прыжком в :Label
ниже цикла FOR, когда значение присваивается переменной среды, чтобы вообще не сталкиваться с этой проблемой.
Другое решение - это то, что используется в этом коде. Из-за использования опции WMIC /VALUE
имя свойства и его значение выводятся в одной строке. Команда FOR выполняет команду SET из-за tokens=2
только когда он может разбить текущую строку как минимум на 2 подстроки (токены), используя знак равенства и точку в качестве разделителей из-за delims==.
, Но неверный обработанный конец вывода WMIC предназначен для строки FOR, содержащей только возврат каретки, и, следовательно, не имеет второго токена. По этой причине неправильно проанализированные пустые строки здесь также игнорируются FOR.
См. Как исправить неправильное поведение при перезаписи переменных при разборе вывода? и cmd каким-то образом пишет китайский текст в качестве вывода для деталей о проблеме синтаксического анализа FOR в кодированном выводе UTF-16 LE.
Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.
echo /?
for /?
set /?
wmic /?
wmic os /?
wmic os get /?
wmic os get localdatetime /?
Вы должны создать профиль Windows для пользователя, который будет использоваться для запуска Задачи, и настроить региональные параметры и формат даты в этом профиле.
У меня была похожая проблема с OP, и мне нравится метод, использующий wmic @Regejok. Вот мое решение для обработки уникальных строк, возвращаемых DOS DATE (решение для США - извините, нет другой операционной системы региона для тестирования, но это может быть довольно быстро реорганизовано для других регионов).
У меня были серверы, которые возвращали разные строки для%DATE% (date /t).
ех. 1 - ср 07/04/2018 (идеально тонкая струна)
ех. 2 - 07/04/2018 (еще одна прекрасная строка, но не удалось выполнить мой пакетный скрипт из-за ссылок на подстроки)
Я использовал этот скрипт, выбирая подстроки из DATE & TIME, чтобы создавать переменные даты / времени для регистрации и архивирования файлов:
ОРИГИНАЛЬНЫЙ СЦЕНАРИЙ
@echo off
set HH=%TIME:~0,1%
if "%HH%"==" " goto addzero
goto hourOK
:addzero
set HH=0%TIME:~1,1%
goto end
:hourOK
set HH=%TIME:~0,2%
:end
set mn=%TIME:~3,2%
set SS=%TIME:~6,2%
set ms=%TIME:~9,2%
set MM=%DATE:~4,2%
set DD=%DATE:~7,2%
set YY=%DATE:~-2%
set CCYY=%DATE:~-4%
set dts=%CCYY%%MM%%DD%%HH%%mn%%SS%%ms%
set dateonly=%CCYY%%MM%%DD%
set monthlog=%CCYY%%MM%
@echo on
Пожалуйста, не судите код.:) Становится лучше.
РЕЗУЛЬТАТЫ ДЛЯ СР 07/04/2018:
C:\>set HH=
C:\>if " " == " " goto addzero
C:\>set HH=09
C:\>goto end
C:\>set mn=30
C:\>set SS=49
C:\>set ms=69
C:\>set MM=07
C:\>set DD=04
C:\>set YY=18
C:\>set CCYY=2018
C:\>set dts=2018070409304969
C:\>set dateonly=20180704
C:\>set monthlog=201807
Это отлично работает с бывшим. 1 строка Я пропустил сокращенный день (ср), и все было хорошо. Пока я не попал на сервер, который вернулся экс. 2.
НЕПРАВИЛЬНЫЕ РЕЗУЛЬТАТЫ ЗА '07/04/2018':
C:\>set HH=
C:\>if " " == " " goto addzero
C:\>set HH=09
C:\>goto end
C:\>set mn=31
C:\>set SS=48
C:\>set ms=59
C:\>set MM=4/
C:\>set DD=01
C:\>set YY=18
C:\>set CCYY=2018
C:\>set dts=20184/0109314859
C:\>set dateonly=20184/01
C:\>set monthlog=20184/
Все метки даты / времени содержали символ '/' (ошибка именования файлов). Это все из-за разницы строк DATE и ссылок на подстроки. ВРЕМЯ было хорошо. Даже при сбое в строках месяца (MM) и дня (DD) я заметил, что двухзначные и четырехзначные переменные года были хорошими (YY и CCYY). Как? Отрицательные ссылки. Это стало самым большим исправлением моего финального сценария. Наряду с заменой строк.
МОЙ НОВЫЙ СЦЕНАРИЙ (мне все еще нравится метод, использующий wmic, это просто альтернативный способ, позволяющий использовать 2 различных типа возврата для DATE, используя только DOS)
01 @echo off
02 set str=%DATE%
03 set str=%str:/=%
04
05 set MM=%str:~-8,2%
06 set DD=%str:~-6,2%
07 set YY=%str:~-2%
08 set CCYY=%str:~-4%
09
10 set HH=%TIME:~0,2%
11 set HH=%HH: =0%
12 set mn=%TIME:~3,2%
13 set SS=%TIME:~6,2%
14 set ms=%TIME:~9,2%
15
16 set _dts=%CCYY%%MM%%DD%%HH%%mn%%SS%%ms%
17 set _dateonly=%CCYY%%MM%%DD%
18 set _monthlog=%CCYY%%MM%
19 @echo on
ЗАМЕТКИ:
строка 2:
'str' var holds the value returned from DATE.
Could be formatted like ex. 1 or ex. 2, does not matter
строка 3:
this is string replacement, all '/' replaced with '' (null).
ex. 1 - 'Wed 07/04/2018' >> 'Wed 07042018', ex. 2 - '07/04/2018' >> '07042018'
строка 5:
this is where negative referencing made both date strings equal (in a sense),
month (MM) starts at '-8' characters from the end of the string in both
examples, length of '2'
строка 6:
Same with day (DD), '-6' characters from end of string, length of '2'
строка 7:
2-digit year (YY) works as it did before (already used negative referencing)
строка 8:
4-digit year (CCYY) works as it did before as well
строка 10:
TIME always returns 2-digits in its hour (HH) position, it just doesn't have
a leading '0' if less than 10, what it does return is a leading space
i.e. %TIME:~0,2% will return ' 9' for 9:00 AM (not desired for date/timestamps)
строка 11:
string replacement to the rescue again, replace all spaces with '0',
turns the ' 9' to '09' (exactly what we want)
строка 12:
minutes, seconds, milliseconds all work as they did previously, using
sub-strings to avoid the colons (':') & the period ('.') in the time stamp
i.e. 10:01:26.29
РЕЗУЛЬТАТЫ ОТ НОВОГО СКРИПТА:
C:\>set str=07/04/2018
C:\>set str=07042018
C:\>set MM=07
C:\>set DD=04
C:\>set YY=18
C:\>set CCYY=2018
C:\>set HH= 9
C:\>set HH=09
C:\>set mn=42
C:\>set SS=26
C:\>set ms=48
C:\>set _dts=2018070409422648
C:\>set _dateonly=20180704
C:\>set _monthlog=201807
C:\>set str=Wed 07/04/2018
C:\>set str=Wed 07042018
C:\>set MM=07
C:\>set DD=04
C:\>set YY=18
C:\>set CCYY=2018
C:\>set HH=10
C:\>set HH=10
C:\>set mn=50
C:\>set SS=55
C:\>set ms=48
C:\>set dts=2018070410505548
C:\>set dateonly=20180704
C:\>set monthlog=201807
Надеюсь это поможет. Это не уникально или не разрушает землю, это просто другой способ.