Пакетный файл для поиска строки в именах каталогов - PullRequest
1 голос
/ 15 сентября 2011

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

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

@echo off
::variables
set AntiVirus1="Initial Value"

IF NOT ERRORLEVEL 0 echo %ERRORLEVEL%
else echo "env. variable created successfully."

for /d %%f in (""%ProgramFiles%\*"") do (
{
    IF NOT ERRORLEVEL 0 echo %ERRORLEVEL%

   echo "%%f"
   if exist /i "*McAfee*" < %%f %AntiVirus1%="McAfee"
   ::find "Norton" < %%f
   ::find "Comodo" < %%f
   ::find "AVG" < %%f

}

echo %AntiVirus1%

@pause

Вывод этого скрипта:

C: \ Users \ Matt \ Desktop> set AntiVirus1 = "Начальное значение" C: \ Users \ Matt \ Desktop>

Может кто-нибудь указать мне, что я делаю неправильно?


ОБНОВЛЕНИЕ Исправленный скрипт, теперь работает, но возвращает неверные результаты:

::@echo off
::variables
set AntiVirus1="Initial Value"

IF NOT ERRORLEVEL 0 (echo %ERRORLEVEL%) ELSE echo "env. variable created successfully."

echo Checking Program Files...
for /d %%f in ("%ProgramFiles%\*") do (
   echo "%%f"
   if %%f=="*adobe*" set AntiVirus1="adobe"
)

echo %AntiVirus1% found

@pause

1 Ответ

2 голосов
/ 15 сентября 2011

Прежде всего, ELSE должен находиться на одной строке с IF или на той же строке с закрывающей скобкой, которая относится к IF. В вашем конкретном случае вы должны изменить свою первую команду IF...ELSE следующим образом:

IF NOT ERRORLEVEL 0 (ECHO %ERRORLEVEL%) ELSE ECHO "env. variable created successfully."

или как это:

IF NOT ERRORLEVEL 0 (
  ECHO %ERRORLEVEL%
) ELSE ECHO "env. variable created successfully."

(Использование заглавных букв и отступов не является обязательным.)

Другие вопросы:

  • Дублированные кавычки в заголовке цикла FOR:

    for /d %%f in (""%ProgramFiles%\*"") do (
    

    должно быть

    for /d %%f in ("%ProgramFiles%\*") do (
    
  • Брекеты ({, }) вокруг тела петли. Они не являются частью синтаксиса цикла (фактически они вообще не являются частью синтаксиса пакетного скриптинга), поэтому их следует отбросить.

  • Нет закрывающих скобок, соответствующих открывающим скобкам после DO. Его следует добавить в отдельной строке после тела цикла.

  • Неправильное использование комментариев в стиле :: в теле цикла. Они не допускаются внутри блоков в скобках. Вместо этого используйте REM.


UPDATE

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

Вот ваш новый измененный скрипт с выделенными изменениями:

::@echo off
::variables
set AntiVirus1="Initial Value"

IF NOT ERRORLEVEL 0 (echo %ERRORLEVEL%) ELSE echo "env. variable created successfully."

<b>SETLOCAL EnableDelayedExpansion</b>

echo Checking Program Files...
for /d %%f in ("%ProgramFiles%\*") do (
   echo "%%f"
   <b>SET "folder=%%f"</b>
   if <b>/I NOT "!folder:adobe=!"=="!folder!"</b> set AntiVirus1="adobe"
)

echo %AntiVirus1% found

@pause

Вот немного объяснений.

Синтаксис ! представляет собой эквивалент расширения с задержкой % и используется только с переменными окружения, не с переменными цикла и не с параметрами командной строки. Задержка расширения необходима, потому что мы находимся в блоке в скобках. Блок в квадратных скобках анализируется полностью перед тем, как он начинает выполняться, поэтому все выражения %var% расширяются (оцениваются) перед началом блока и не изменяются в течение всего выполнения блока. Это не может нас устраивать, потому что нам нужно присвоить разные значения переменной во время выполнения блока, а значения должны быть прочитаны внутри блока. Задержка раскрытия, как следует из названия, задерживает раскрытие переменной до фактического выполнения каждой отдельной команды, которая ссылается на эту переменную. Поскольку немедленное расширение все еще может использоваться вместе с отложенным расширением, вводится другой синтаксис, который ! вокруг имен переменных, а не %.

!folder:adobe=! означает оценку folder, заменяя каждое вхождение adobe пустой строкой. Результат этого выражения затем сравнивается с (неизменным) значением folder. Если есть совпадение, то замена не произошла, а это значит, что adobe в значении folder не было. В этом случае мы ничего не должны делать. Но если совпадение было , а не , то есть если измененное значение не совпадало с неизмененным, то мы должны установить переменную AntiVirus1. Вот почему перед сравнением стоит NOT.

Опция /I означает сравнение без учета регистра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...