Сравнение пакетных файлов переменной с константой

Я хочу написать простую часть кода, чтобы получить красивую образованную «метку времени». Получение времени в моих двух переменных Start and End отлично работает. Также я могу напечатать его как 0: 0: 0. Я хочу иметь начальный ноль, если его меньше 10, но, видимо, я получаю сообщение об ошибке «параметр 10 не найден или ошибочен». Я узнал, что это, кажется, переменная, которую нужно сравнить, но я не смог ее исправить. Есть идеи?

 @ECHO OFF REM Time Calculation FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."') DO ( set Day=%%A set Hour=%%B set Minute=%%C set Second=%%D ) set /a Start=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100 @ECHO ON ping 8.8.8.8 -n 11 @ECHO OFF FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."') DO ( set Day=%%A set Hour=%%B set Minute=%%C set Second=%%D ) set /a End=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100 set /a Diff=%End%-%Start% set /a Diff=(%Diff%)/100 set /a DiffSec=%Diff%%%60 set /a Diff=(%Diff%-%Diff%%%60)/60 set /a DiffMin=%Diff%%%60 set /a Diff=(%Diff%-%Diff%%%60)/60 set /a DiffHrs=%Diff% ECHO Laufzeit Auftraege loeschen: %DiffHrs%:%DiffMin%:%DiffSec% :: format with leading zeroes if %DiffSec% LSS 10 (ECHO "LESS 10")else %DiffSec% LSS 1 (ECHO "LESS 1") ::if %DiffSec% LSS 10 (set DiffSec=0%DiffSec%)else [%DiffSec%] LSS 1 (set DiffSec=00) ::if %DiffMin% LSS 10 (set DiffMin=0%DiffMin%)else [%DiffMin%] LSS 1 (set DiffMin=00) ::if %DiffHrs% LSS 10 (set DiffHrs=0%DiffHrs%)else [%DiffHrs%] LSS 1 (set DiffHrs=00) ECHO Laufzeit Auftraege loeschen: %DiffHrs%:%DiffMin%:%DiffSec% 

1. Отладка командного файла

Для отладки командного файла для поиска синтаксических ошибок в коде рекомендуется запускать командный файл из windows командной строки после того, как каждое echo off изменено для echo off или echo off из пакетного файла или закомментировано командой REM .

По умолчанию интерпретатор команд Windows выводит каждую командную строку или весь командный блок, начиная с ( и заканчивая согласованием ) после синтаксического анализа и предварительной обработки, на которые переменные среды, на которые ссылается %variable% (немедленное расширение), уже заменены текущим значением переменной среды до выполнение командной строки / блока.

С @echo off в верхней части командного файла это поведение по умолчанию отключается, в результате чего @ в начале командной строки также отключает вывод этой первой командной строки. Это, конечно, приветствуется, когда завершается разработка командного файла, и командный файл работает нормально. Но для отладки командного файла, который работает не так, как ожидалось, лучше видеть также командные строки, реально выполняемые интерпретатором команд, чтобы выяснить, откуда выполнение пакетного файла неожиданно из-за ошибки.

Поведение ECHO объясняется очень кратко в справочном отчете о запуске echo /? из windows командной строки.

Открытие windows командной строки приводит к тому, что cmd.exe неявно запускается с параметром /K чтобы продолжить выполнение командного процесса и открыть консольное окно после завершения исполнения командного файла или приложения.

Исключением является то, что командный файл содержит команду exit без параметра /B поскольку в этом случае текущий командный процесс всегда выходит из независимой иерархии вызовов. exit /B равен goto :EOF и должен использоваться вместо exit за исключением того, что есть действительно хорошая причина для использования только exit . exit /B и goto :EOF требует, чтобы оба расширения команд были включены по умолчанию в Windows.

Двойной щелчок по пакетному файлу приводит к запуску cmd.exe с опцией /C для автоматического закрытия процесса команды и ее windows консоли при завершении выполнения приложения или командного файла независимо от причины прекращения исполнения пакетного файла. Такое поведение при автоматическом закрытии windows консоли не подходит для отладки командного файла, потому что сообщение об ошибке не видно, когда выполнение пакетного файла завершается из-за синтаксической ошибки.

Подробнее о параметрах интерпретатора команд Windows запустите в окне командной строки команду: cmd /?

Как умышленно выйти из командного файла с помощью goto :EOF (двоеточие здесь важно с помощью исключения) или exit /B (только внутренний псевдоним для goto :EOF ) объясняется с помощью этих двух команд, отображаемых при запуске goto /? и exit /? в окне командной строки.

Для отладки более крупного командного файла может быть полезно использовать временно добавленную goto в верхней части командного файла, чтобы перейти к определенному блоку и goto :EOF чтобы завершить пакетную обработку после блока для отладки.

Кстати: :: это недопустимый ярлык, часто используемый для комментариев в пакетных файлах, поскольку строки ярлыков никогда не отображаются при выполнении командного файла. Но в командном блоке метки цикла FOR нельзя использовать, потому что интерпретатор команд Windows не может интерпретировать правый цикл FOR с метками внутри блока команд. По этой причине лучше использовать команду REM (примечание) для комментариев, поскольку эта команда предназначена для комментариев в пакетных файлах и действительно работает в любом месте в пакетном файле.

2. Ошибка в пакетном файле

При запуске командного файла, размещенного в вопросе, оба из которых @ECHO OFF закомментированы, заменив его на rem @echo off (запустите замену в текстовом редакторе) из windows командной строки, можно легко увидеть, на какой строке возникает ошибка:

 if %DiffSec% LSS 10 (ECHO "LESS 10")else %DiffSec% LSS 1 (ECHO "LESS 1") 

Если текущее значение переменной окружения DiffSec не ниже 10 то ветвь ELSE выполняется интерпретатором команд Windows, который начинается с числа, такого как 10 .

Командный интерпретатор Windows не может найти приложение с этим именем в текущем каталоге или в любом каталоге, указанном в разделенном запятой списке каталогов переменной окружения PATH имеющем расширение файла, указанное в списке расширений файлов с разделителями с запятой, переменной среды PATHEXT .

Ошибка здесь явно отсутствует в команде IF для следующего сравнения. Таким образом, правильный код будет

 if %DiffSec% LSS 10 (ECHO "LESS 10") else if %DiffSec% LSS 1 ECHO "LESS 1" 

Это было бы легче прочитать при написании условия на нескольких строках:

 if %DiffSec% LSS 10 ( ECHO "LESS 10" ) else if %DiffSec% LSS 1 ( ECHO "LESS 1" ) 

Синтаксис теперь корректен.

Но второе условие не имеет смысла, как упомянул ЙозефZ в своем комментарии. Если значение DiffSec равно 10 или больше, что приводит к выполнению команды IF в ветке ELSE , это условие, безусловно, также неверно. Так что больше смысла будет:

 if %DiffSec% LSS 1 (ECHO LESS 1) else if %DiffSec% LSS 10 ECHO LESS 10 

Или альтернативно

 if %DiffSec% LSS 1 ( ECHO LESS 1 ) else if %DiffSec% LSS 10 ( ECHO LESS 10 ) 

Для получения дополнительной информации о действительных условиях IF ELSE в пакетных файлах см., Например, ответы на

  • ЕСЛИ ELSE синтаксическая ошибка в пакетном файле?
  • пакетный скриптинг – если есть ./sdcard/file.any с помощью adb

3. Добавьте начальный ноль для чисел <10

Переменные среды всегда имеют строку типа. Для арифметических выражений строковое значение переменной среды преобразуется в 32-битовое целое, если это возможно вообще, и результат арифметического выражения преобразуется обратно из 32-битного целого числа в строку.

Также условие IF, например, if %DiffSec% LSS 10 до выполнения, например, if 5 LSS 10 приводит к преобразованию 5 (0x35) из строки в целое и 10 (0x31 0x30) также из строки в целое число для сравнения двух чисел как целые числа.

Поэтому было бы немного быстрее избежать такого сравнения чисел, если это возможно.

Достаточно легко добавить начальный ноль к числу ниже 10, не испытывая при этом значения, используя замену строк.

Сначала текущее значение переменной окружения добавляется с одним (для двухзначного числа) или более 0 (для 3, 4 или даже больше цифр).

 set "DiffSec=0%DiffSec%" 

Затем последним символам X, таким как 2 для двухзначного числа, присваивается текущее значение переменной среды переменной среды.

 set "DiffSec=%DiffSec:~-2%" 

Подстановка строк объясняется с помощью команды SET output, запуская в окне командной строки set /? ,

Результатом двух строк является то, что DiffSec имеет значения от 0 до 99 после того, как эти две строки всегда представляют собой двухзначное число в диапазоне от 00 до 99 .

4. Анализ арифметического выражения

Арифметическое выражение, которое является строкой после set /a , интерпретируется интерпретатором команд Windows, полностью отличным от других строк.

Пробелы и вкладки являются разделителями слов, но не имеют особого значения. Поэтому целесообразно использовать пробелы, чтобы сделать арифметическое выражение более читаемым.

Тогда есть много операторов, которые перечислены с помощью команды SET, отображаемой при запуске в окне командной строки set /? ,

Дальнейшие десятичные, восьмеричные и шестнадцатеричные целые числа интерпретируются в арифметическом выражении как целые числа.

И последняя каждая строка интерпретируется как имя переменной среды, из которой текущее значение преобразуется из строки в целое.

По этой причине нецелесообразно использовать немедленное или замедленное расширение в арифметическом выражении.

Ссылка на значение переменной среды с %variable% пределах арифметического выражения не является хорошей при использовании в командном блоке, в котором текущее значение переменной среды заменяет ссылку на переменную уже при parsingе всего командного блока перед выполнением первой команды.

Ссылка на значение переменной среды с !variable! в рамках арифметического выражения также не является хорошим, потому что для этого требуется возможность отсроченного расширения, что приводит к обработке восклицательных знаков в строках больше не как буквенные символы.

Поэтому лучше всего просто писать имена переменных в арифметическом выражении без окружающих знаков процента или восклицательных знаков, если это возможно из-за имени переменной, не содержит пробела и начинается с символа, который не может быть интерпретирован как целочисленный символ Windows командный интерпретатор.

См. Также ответ на вопрос Почему нет строки вывода с ‘echo% var%’ после использования ‘set var = text’ в командной строке? для получения подробных сведений о том, как назначить значение переменной среды, используя только set или set /P (приглашение) или set /A (арифметическое выражение).

5. Исправлен и оптимизирован код

Этот код может быть исправлен и оптимизирован для этого кода:

 @echo off rem Time Calculation for /F "skip=1 tokens=1-4" %%A in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_LocalTime GET Day^,Hour^,Minute^,Second') do ( set Day=%%A set Hour=%%B set Minute=%%C set Second=%%D ) set /A TimeStart=Day * 86400 + Hour * 3600 + Minute *60 + Second @echo on %SystemRoot%\System32\ping.exe 8.8.8.8 -n 11 @echo off for /F "skip=1 tokens=1-4" %%A in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_LocalTime GET Day^,Hour^,Minute^,Second') do ( set Day=%%A set Hour=%%B set Minute=%%C set Second=%%D ) set /A TimeEnd=Day * 86400 + Hour * 3600 + Minute *60 + Second set /A TimeDiff=TimeEnd - TimeStart set /A DiffSec=TimeDiff %% 60 set /A TimeDiff=(TimeDiff - DiffSec) / 60 set /A DiffMin= TimeDiff %% 60 set /A DiffHrs=(TimeDiff - DiffMin) / 60 set "DiffSec=0%DiffSec%" set "DiffSec=%DiffSec:~-2%" set "DiffMin=0%DiffMin%" set "DiffMin=%DiffMin:~-2%" set "DiffHrs=0%DiffHrs%" set "DiffHrs=%DiffHrs:~-2%" echo Time needed for orders deletion: %DiffHrs%:%DiffMin%:%DiffSec% 

Чтобы понять используемые команды и как они работают, откройте окно командной строки, выполните там следующие команды и тщательно прочитайте все страницы справки, отображаемые для каждой команды.

  • echo /?
  • for /?
  • ping /?
  • rem /?
  • set /?
  • wmic /?
  • wmic path /?
 if %DiffSec% LSS 10 (ECHO "LESS 10")else IF %DiffSec% LSS 1 (ECHO "LESS 1") 

вам нужно, if после else .

  • Удалить определенные строки в txt-файле через пакетный файл
  • Случайный генератор в партии
  • Почему (или когда) Rscript (или littler) лучше, чем R CMD BATCH?
  • Как запустить пакетный скрипт (.bat-файл) из eclipse
  • команды набора не работают в моем командном файле
  • Отображение вывода командной строки Windows и redirect ее в файл
  • Как проверить размер файла в пакетном скрипте Windows?
  • Цвет партии в строке
  • Меньше или равно
  • Как сделать одну конкретную строку командного файла другим цветом, чем другие?
  • Пакетные файлы окон: настройка переменной для цикла
  • Давайте будем гением компьютера.