Запрет на запуск bat файлов
Бат-файлы ведут свою историю со времен MS-DOS. Новые фичи добавлялись с сохранением обратной совместимости. Из-за этого многое в языке bat-файлов, как мы увидим далее, нелогично и неудобно.
Вместе с тем, в bat-файле можно использовать переменные, условия, циклы и подпрограммы. При помощи некоторых костылей можно передавать данные на вход команд и разбирать их вывод. Проще говоря, можно программировать.
В этой статье мы постараемся дать обзор основных элементов языка командного интерпретатора Windows, с помощью которых можно реализовать любой алгоритм.
Зачем же сегодня использовать этот язык? Главным образом, для автоматизации выполнения консольных команд. Запуск команд выполняется в bat-файле проще, чем в каком-либо другом языке: инструкция запуска команды – это сама команда без каких бы то ни было ключевых слов, знаков препинания и подключаемых библиотек.
Язык C++ сам по себе вообще не определяет для этого стандартный и независимый от платформы способ. Тут вам понадобится библиотека целевой операционной системы. В Windows это windows.h и функция CreateProcess() , а в Linux надо вызвать fork() , а затем exec() .
Второе место по простоте вызова команд операционной системы занимает Perl – в нем достаточно заключить команду в обратные кавычки ( `` ).
Первое место с bat-файлами делят PowerShell и bash.
Прежде всего, ради искусства. Разные люди делают интересные вещи чисто на bat-файлах именно потому, что это сложно. Т.е. можно рассматривать язык командного интерпретатора как эзотерический язык программирования.
Кроме того, как-то раз в реальном проекте мне пришлось поддерживать bat-скрипты. Так что рано их списывать со счетов как морально устаревшую технологию.
Еще одно полезное отличительное свойство командного интерпретатора – для получения справки не нужен ни Гугл, ни интернет. Нужно лишь набрать команду help . Причем, информация русском языке, если у вас русская винда.
Заключение
Язык командного интерпретатора имеет многолетнюю историю и дожил до наших дней. Он доступен на чистой винде и удобен для автоматизации выполнения команд. При этом он является языком программирования, и позволяет реализовать алгоритмы любой сложности. Самое главное в таком деле – найти подходящие инструменты командной строки, дающие доступ к нужным возможностям. Вместе с тем решение задач на bat-файлах с использованием ограниченного набора внешних команд может быть интересным упражнением.
Тогда предлагаю предварительно почитать
Создание политик AppLocker
Прочитав многие вопросы отпадут сами собой.
The opinion expressed by me is not an official position of Microsoft
Только учтите что скрипты как правило запускаются не сами по себе, а в интерпретаторе (cmd, wscript и прочих)
что означает что нужно так же блокировать приложения которые их собственно выполняют
The opinion expressed by me is not an official position of Microsoft
Вообще-то - не нужно: интерпретаторы сами обращаются к AppLocker, чтобы проверить, можно ли исполнять скрипт.
Вообще-то - не нужно: интерпретаторы сами обращаются к AppLocker, чтобы проверить, можно ли исполнять скрипт.
Слава России!
Вполне возможно, но по идее если скрипт запускать в уже запущенной консоли, скрипт будет прочтен а не выполнен. из этой логики ХЗ как отработает аплокер. Если проблем не возникнет то ок, если возникнут можно еще в эту сторону посмотреть
The opinion expressed by me is not an official position of Microsoft
Создал политику, положил её в папку домена (в смысле применяется ко всему домену). В самой политике выставил запретить пользователям "все" открывать путь *.vbs
Написал простетский скрипт .vbs
Запускаю его где хочу и под каким хочу пользователем.
Вот скрин политики. Что не так ?
applocker доступен на ентерпрайсных редакциях клиентских ос
проверьте на сервере
The opinion expressed by me is not an official position of Microsoft
Запускается на сервере 2012 R2, на сервере 2008 R2 Enterprise, на клиентских windows 7.
applocker доступен на ентерпрайсных редакциях клиентских ос
проверьте на сервере
The opinion expressed by me is not an official position of Microsoft
Извиняюсь, немного не понял что именно проверить?
На клиентах у меня везде windows 7 ultimate.
Спасибо. Исправил, но почему-то это не помогло.
Извиняюсь, немного не понял что именно проверить?
На клиентах у меня везде windows 7 ultimate.
Для того что бы аплокер отрабатывал должна быть запущена служба, название наверняка есть в статье выше, проверьте этот момент + проверьте теже действия (отрабатывает ли политика на серверной ОС) если вы это делаете через доменные политики
The opinion expressed by me is not an official position of Microsoft
Вообще-то - не нужно: интерпретаторы сами обращаются к AppLocker, чтобы проверить, можно ли исполнять скрипт.
Слава России!
Вполне возможно, но по идее если скрипт запускать в уже запущенной консоли, скрипт будет прочтен а не выполнен. из этой логики ХЗ как отработает аплокер. Если проблем не возникнет то ок, если возникнут можно еще в эту сторону посмотретьThe opinion expressed by me is not an official position of Microsoft
Нет, проверка зашита внутрь интерпретаторов, и при попытке "прочитать" заблокированный политикой файл будет выдана ошибка. Буквально только что описал такую ситуацию SCCM,Application,Powershell – software restriction policy
Политику настроил и она работала, но она работала на ВЕСЬ домен, хотя в правилах запрета скриптов были выбраны только нужные мне группы.
Удалил политику. Создал подразделение специально для неё, в это подразделение добавил специальную группу, в эту группу добавил уже нужные мне группы пользователей, чтобы запрет действовал только на них.
Всё вроде настроил по аналогии, от предыдущей политики, но она всё равно не применяется к нужным мне пользователям. Вот скрин политики. В чём может быть проблема ?
Политику настроил и она работала, но она работала на ВЕСЬ домен, хотя в правилах запрета скриптов были выбраны только нужные мне группы.
Удалил политику. Создал подразделение специально для неё, в это подразделение добавил специальную группу, в эту группу добавил уже нужные мне группы пользователей, чтобы запрет действовал только на них.
Всё вроде настроил по аналогии, от предыдущей политики, но она всё равно не применяется к нужным мне пользователям. Вот скрин политики. В чём может быть проблема ?
я правильно понимаю что вы политику компьютера пытаетесь применить к пользователям?
Старайтесь делать группы разрешения и запрета таким образом что бы они не пересекались, иначе поведение будет трудно прогнозируемым
Тогда предлагаю предварительно почитать
Создание политик AppLocker
Прочитав многие вопросы отпадут сами собой.
The opinion expressed by me is not an official position of Microsoft
Только учтите что скрипты как правило запускаются не сами по себе, а в интерпретаторе (cmd, wscript и прочих)
что означает что нужно так же блокировать приложения которые их собственно выполняют
The opinion expressed by me is not an official position of Microsoft
Вообще-то - не нужно: интерпретаторы сами обращаются к AppLocker, чтобы проверить, можно ли исполнять скрипт.
Вообще-то - не нужно: интерпретаторы сами обращаются к AppLocker, чтобы проверить, можно ли исполнять скрипт.
Слава России!
Вполне возможно, но по идее если скрипт запускать в уже запущенной консоли, скрипт будет прочтен а не выполнен. из этой логики ХЗ как отработает аплокер. Если проблем не возникнет то ок, если возникнут можно еще в эту сторону посмотреть
The opinion expressed by me is not an official position of Microsoft
Создал политику, положил её в папку домена (в смысле применяется ко всему домену). В самой политике выставил запретить пользователям "все" открывать путь *.vbs
Написал простетский скрипт .vbs
Запускаю его где хочу и под каким хочу пользователем.
Вот скрин политики. Что не так ?
applocker доступен на ентерпрайсных редакциях клиентских ос
проверьте на сервере
The opinion expressed by me is not an official position of Microsoft
Запускается на сервере 2012 R2, на сервере 2008 R2 Enterprise, на клиентских windows 7.
applocker доступен на ентерпрайсных редакциях клиентских ос
проверьте на сервере
The opinion expressed by me is not an official position of Microsoft
Извиняюсь, немного не понял что именно проверить?
На клиентах у меня везде windows 7 ultimate.
Спасибо. Исправил, но почему-то это не помогло.
Извиняюсь, немного не понял что именно проверить?
На клиентах у меня везде windows 7 ultimate.
Для того что бы аплокер отрабатывал должна быть запущена служба, название наверняка есть в статье выше, проверьте этот момент + проверьте теже действия (отрабатывает ли политика на серверной ОС) если вы это делаете через доменные политики
The opinion expressed by me is not an official position of Microsoft
Вообще-то - не нужно: интерпретаторы сами обращаются к AppLocker, чтобы проверить, можно ли исполнять скрипт.
Слава России!
Вполне возможно, но по идее если скрипт запускать в уже запущенной консоли, скрипт будет прочтен а не выполнен. из этой логики ХЗ как отработает аплокер. Если проблем не возникнет то ок, если возникнут можно еще в эту сторону посмотретьThe opinion expressed by me is not an official position of Microsoft
Нет, проверка зашита внутрь интерпретаторов, и при попытке "прочитать" заблокированный политикой файл будет выдана ошибка. Буквально только что описал такую ситуацию SCCM,Application,Powershell – software restriction policy
Политику настроил и она работала, но она работала на ВЕСЬ домен, хотя в правилах запрета скриптов были выбраны только нужные мне группы.
Удалил политику. Создал подразделение специально для неё, в это подразделение добавил специальную группу, в эту группу добавил уже нужные мне группы пользователей, чтобы запрет действовал только на них.
Всё вроде настроил по аналогии, от предыдущей политики, но она всё равно не применяется к нужным мне пользователям. Вот скрин политики. В чём может быть проблема ?
Политику настроил и она работала, но она работала на ВЕСЬ домен, хотя в правилах запрета скриптов были выбраны только нужные мне группы.
Удалил политику. Создал подразделение специально для неё, в это подразделение добавил специальную группу, в эту группу добавил уже нужные мне группы пользователей, чтобы запрет действовал только на них.
Всё вроде настроил по аналогии, от предыдущей политики, но она всё равно не применяется к нужным мне пользователям. Вот скрин политики. В чём может быть проблема ?
я правильно понимаю что вы политику компьютера пытаетесь применить к пользователям?
Старайтесь делать группы разрешения и запрета таким образом что бы они не пересекались, иначе поведение будет трудно прогнозируемым
Тогда предлагаю предварительно почитать
Создание политик AppLocker
Прочитав многие вопросы отпадут сами собой.
The opinion expressed by me is not an official position of Microsoft
Только учтите что скрипты как правило запускаются не сами по себе, а в интерпретаторе (cmd, wscript и прочих)
что означает что нужно так же блокировать приложения которые их собственно выполняют
The opinion expressed by me is not an official position of Microsoft
Вообще-то - не нужно: интерпретаторы сами обращаются к AppLocker, чтобы проверить, можно ли исполнять скрипт.
Вообще-то - не нужно: интерпретаторы сами обращаются к AppLocker, чтобы проверить, можно ли исполнять скрипт.
Слава России!
Вполне возможно, но по идее если скрипт запускать в уже запущенной консоли, скрипт будет прочтен а не выполнен. из этой логики ХЗ как отработает аплокер. Если проблем не возникнет то ок, если возникнут можно еще в эту сторону посмотреть
The opinion expressed by me is not an official position of Microsoft
Создал политику, положил её в папку домена (в смысле применяется ко всему домену). В самой политике выставил запретить пользователям "все" открывать путь *.vbs
Написал простетский скрипт .vbs
Запускаю его где хочу и под каким хочу пользователем.
Вот скрин политики. Что не так ?
applocker доступен на ентерпрайсных редакциях клиентских ос
проверьте на сервере
The opinion expressed by me is not an official position of Microsoft
Запускается на сервере 2012 R2, на сервере 2008 R2 Enterprise, на клиентских windows 7.
applocker доступен на ентерпрайсных редакциях клиентских ос
проверьте на сервере
The opinion expressed by me is not an official position of Microsoft
Извиняюсь, немного не понял что именно проверить?
На клиентах у меня везде windows 7 ultimate.
Спасибо. Исправил, но почему-то это не помогло.
Извиняюсь, немного не понял что именно проверить?
На клиентах у меня везде windows 7 ultimate.
Для того что бы аплокер отрабатывал должна быть запущена служба, название наверняка есть в статье выше, проверьте этот момент + проверьте теже действия (отрабатывает ли политика на серверной ОС) если вы это делаете через доменные политики
The opinion expressed by me is not an official position of Microsoft
Вообще-то - не нужно: интерпретаторы сами обращаются к AppLocker, чтобы проверить, можно ли исполнять скрипт.
Слава России!
Вполне возможно, но по идее если скрипт запускать в уже запущенной консоли, скрипт будет прочтен а не выполнен. из этой логики ХЗ как отработает аплокер. Если проблем не возникнет то ок, если возникнут можно еще в эту сторону посмотретьThe opinion expressed by me is not an official position of Microsoft
Нет, проверка зашита внутрь интерпретаторов, и при попытке "прочитать" заблокированный политикой файл будет выдана ошибка. Буквально только что описал такую ситуацию SCCM,Application,Powershell – software restriction policy
Политику настроил и она работала, но она работала на ВЕСЬ домен, хотя в правилах запрета скриптов были выбраны только нужные мне группы.
Удалил политику. Создал подразделение специально для неё, в это подразделение добавил специальную группу, в эту группу добавил уже нужные мне группы пользователей, чтобы запрет действовал только на них.
Всё вроде настроил по аналогии, от предыдущей политики, но она всё равно не применяется к нужным мне пользователям. Вот скрин политики. В чём может быть проблема ?
Политику настроил и она работала, но она работала на ВЕСЬ домен, хотя в правилах запрета скриптов были выбраны только нужные мне группы.
Удалил политику. Создал подразделение специально для неё, в это подразделение добавил специальную группу, в эту группу добавил уже нужные мне группы пользователей, чтобы запрет действовал только на них.
Всё вроде настроил по аналогии, от предыдущей политики, но она всё равно не применяется к нужным мне пользователям. Вот скрин политики. В чём может быть проблема ?
я правильно понимаю что вы политику компьютера пытаетесь применить к пользователям?
Старайтесь делать группы разрешения и запрета таким образом что бы они не пересекались, иначе поведение будет трудно прогнозируемым
Многие программисты программного обеспечения сталкивались с задачей запрета запуска копий приложения. Это делается с различными целями и зависит от ситуации. Существует даже отдельный термин для решения данной задачи — Mutex.
Также данная задача иногда возникает перед системными администраторами с тем отличием, что приложение стороннее (разработано другой организацией). Эта статья описывает относительно простой способ решения проблемы запрета запуска копий стороннего приложения.
Задача
Как то раз у меня на работе возникла проблема — некоторые сотрудники умудрялись запускать несколько копий приложений. Запуск нескольких копий, конечно, не приводил к катастрофическим результатам, но иногда порождал различные «глюки», нестабильную работу программы. Это, естественно, добавляло мне головной боли от многочисленных жалоб на эти «глюки».
Первым делом я провел разъяснительную беседу с сотрудниками о проблеме запуска копий приложения и о том, как этого избежать. Данная мера помогла на ближайшие пару дней, а далее всё вернулось на круги своя. Жаловаться начальству на такое попустительство некоторых работников было чревато моим увольнением, т.к. начальство безумно ценило этих работников, а ко мне отношение было кардинально противоположным.
Как говориться «Раз гора не идёт к Магомету, то Магомет идёт к горе». Я решил сам программно запретить запуск копий приложения. Задача оказалась не тривиальная.
Несложный анализ выявил 2 особенности моей ситуации:
Во-первых, у меня приложение стороннее, т.е. его разработчик не наша организация и доступа к исходному коду нет (поясню, приложение — один из продуктов Microsoft). Каких-либо регулирующих запуск настроек и параметров приложение не имеет.
Во-вторых, приложение запускается не напрямую, а как программа по умолчанию для открытия файлов определённого расширения. То есть приложение запускается с параметром (путь файла данных, который нужно открыть).
Решение — теория
Поиск в Интернете не дал мне явного решения. Запрета запуска второй копии приложения в виде системных настроек, как я понял не существует (хотя есть API). Также я нашел десятки примеров реализации mutex-ов на различных языках программирования, но все они, естественно, требовали внесения изменений в код и мне не подходили. Надо было искать своё оригинальное решение, и желательно попроще.
- Пользователь инициирует запуск приложения, открывая файл данных, ассоциируемый с приложением.
- По умолчанию вместо требуемого приложения запускается приложение-прослойка.
- Это приложение получает в виде параметра путь к файлу данных, создаёт mutex и запускает требуемое приложение с полученными параметрами. Приложение-прослойка, соответственно, должно быть скрыто.
- Далее запускается требуемое приложение и пользователь работает в нём. Приложение-прослойка всё это время продолжает работу. Его mutex блокирует попытки запуска копии.
- По окончанию работы пользователь закрывает основную программу. Программа-прослойка закрывается автоматически.
Решение — практика
Практическое решение приведено для приложения «Блокнот» (понятное дело, что на его месте может быть любое приложение).
Программный код скрипта (текстовый файл с расширением .au3) не представляет ничего сложного:
Хабраюзер mayorovp правильно отметил, что название семафора «Mutex» лучше заменить на что-то более уникальное.
Как вы сами видите, весь код условно можно разделить на две части: mutex и запуск требуемого приложения. Более детально я объяснять не буду, т.к. статья посвящена не изучению возможностей AutoIt.
Написав скрипт его можно откомпилировать либо в редакторе SciTE Script Editor, либо через контекстное меню файла (правый клик по файлу скрипта). После чего его уже можно использовать. Можно также откомпилировать с дополнительными настройками (битность системы и иконка приложения) при помощи утилиты Aut2Exe, которая также идёт в комплекте с AutoIt.
Далее всё элементарно — помещаем получившееся приложение-прослойку в какую-нибудь директорию и настраиваем открытие по умолчанию для файлов данных (в примере для файлов с расширением .txt) при помощи этого приложения-прослойки.
На этом всё. Проверяем и радуемся решенной задаче — теперь никто не сможет запустить две копии «Блокнота».
Послесловие
Данный способ позволил мне решить проблему двойного запуска приложений. Правда, на следующий день после установки приложения-прослойки ко мне прибежали нерадивые сотрудники со словами «Оно не запускается». Пришлось провести разъяснительную беседу с сотрудниками на тему «Приложение не запускается, потому что уже запущено». Эта беседа оказалась куда эффективнее, т.к. особого выбора у сотрудников не было. Уже почти месяц данных проблем не возникало.
Если кто из читателей знает способ написать mutex в виде .bat файла для данной задачи, то поделитесь опытом. У меня есть подозрение, что такой способ есть.
Ввод пользователя
SET /P A=Enter something:
Выведет приглашение для ввода и будет ждать ввода строки. Введенная строка окажется в переменной A.
Вызов подпрограмм и других скриптов
Очередная контринтуитивная фича bat-файлов в том, что, если из одного bat-файла вызвать другой, выполнение первого файла не продолжится, если только не использовать ключевое слово call. То есть, мы должны разбираться, чем является команда, которую мы хотим вызвать. Если это bat-файл, то надо перед его именем написать call. Если это exe-файл или встроенная команда, то это слово не нужно. Кроме того, если вызываемый скрипт использует команду exit , то выполнение также не вернется к нам. Чтобы завершить только текущий скрипт, надо писать exit /B .
При вызове одного скрипта из другого не создается новый процесс. Поэтому переменные окружения, установленные вызванным скриптом, видны вызывающему.
В следующем примере a.bat вызывает b.bat . Этот пример также демонстрирует работу с кодом завершения процесса.
Командой call также можно вызвать код, находящийся в том же файле:
Работает аналогично предыдущему примеру, но это один файл.
С двоеточия начинаются метки. На них можно переходить командами call и goto . В языке bat-файлов нет понятия подпрограммы. Мы будем так называть код, который вызывается через call и возвращает управление через exit /B или goto :eof . Метка :eof не определена, и это не ошибка. Эта метка не нуждается в определении. Она всегда означает конец файла. Т.е. переход на :eof – это выход – то же, что и exit /B , но без кода завершения.
Специальные переменные
Переменные, перечисленные ниже, используют один знак %, только в начале, в отличие от обычных переменных.
%0 – имя bat-файла, который сейчас выполняется, в том виде, как оно указано в командной строке. Для запуска bat-файла его имя может быть написано с полным путем, с относительным путем, без пути, с расширением, без расширения, маленькими или заглавными буквами. Соответственно, в переменной %0 оно может оказаться во всех этих вариантах. Но в любом случае командой %0 скрипт запускает сам себя.
%1, %2 … %9 – параметры. Командная строка разделяется на токены по пробелам. При этом каждая часть, заключенная в кавычки, считается одним токеном. Кавычки, если есть, тоже попадают в эти переменные.
%* – все параметры, т.е. всё, что идет в командной строке после имени bat-файла, со всеми кавычками и пробелами, какие есть.
%errorlevel% - код возврата последней команды
%CD% - текущая директория
%DATE% и %TIME% - текущие дата и время
%RANDOM% - случайное число
Разыменование переменных
Отсутствие в языке массивов и словарей приходится обходить, используя переменные, имена которых содержат индексы и ключи.
Допустим, переменная A содержит ключ:
Записать значение по ключу можно так:
Следующая команда выведет «bbb»:
А вот читать по ключу не так просто. Подстановка переменных не рекурсивна. То есть, нельзя, используя только знак « % », подставить «aaa» вместо «A», а затем, «bbb» вместо «aaa».
Тут нам поможет поздняя подстановка. Она тоже не рекурсивна. Однако, используя сразу оба вида подстановок, можно выполнить замену в два этапа:
Желающие усложнить себе задачу отказом от поздней подстановки, могут разбирать вывод команды set при помощи цикла for:
for /F "tokens=1,2 delims==" %%a in ('set %A%') do if "%%a"=="%A%" echo %%b
Обратите внимание, что в цикле надо проверять имя переменной, которую нам вернули, даже если указать имя нужной переменной в команде set. Дело в том, что могут существовать переменные с именами, начинающимися с нужного. Если убрать параметр команды set, результат не изменится. Но указывая этот параметр, мы оптимизируем алгоритм. Но это не точно.
Цикл по числам с заданным шагом
Используем параметр /L, а в скобках указываем начало, шаг и конец (включительно) через запятую. Обратите внимание, что для числа, указанного как конец интервала, команда тоже будет вызвана, если длина интервала делится на шаг. Шаг может быть отрицательным.
FOR /L %%a in (10,-1,5) do @echo %%a
Арифметика
Команда set /A вычисляет выражения
Разбор файлов и строк
FOR /F %%a in (список.txt список2.txt) do echo %%a
Каждый файл открывается, каждая строка читается и разбивается на одну или более подстрок. Подстроки записываются в отдельные переменные. Например, если переменная цикла - %%a, то будут созданы переменные %%a, %%b, %%c и т.д.
При разборе строки разделителями по умолчанию считаются пробелы и табуляции.
Вот так можно разобрать строку, указанную непосредственно:
FOR /F %%a in (“строка”) do echo %%a
А так разбирается вывод команды. Это вообще единственный способ получить вывод команды в переменную. То есть, даже если вывод состоит из одной строки, и ее не надо разбирать, всё равно приходится писать цикл.
FOR /F %%a (‘dir /B’) do echo %%a
Выводит список файлов, разбирая вывод команды dir .
Наберите help for , чтобы узнать все опции.
Переменные
Переменные в bat-файлах – это переменные окружения. Это значит, что все переменные, установленные скриптом, доступны процессам, которые он запускает. Это надо иметь ввиду при работе с паролями.
Переменные создаются и изменяются командой set :
Создали переменную с именем hello и значением world.
Команда set без параметров выводит список всех переменных.
Следующая строка выведет слово "world":
Имена переменных нечувствительны к регистру. Следующая строка тоже выведет слово "world":
Значения переменных могут содержать знак равенства:
Значение переменных вставляются в текст команды, и только потом происходит ее разбор. Это значит, что переменная может содержать саму команду и/или любое количество параметров.
Цикл FOR
Это единственный вид цикла. Если нужно что-то типа while или until, то придется использовать операторы if и goto.
Зато цикл FOR имеет несколько опций, выходящих за рамки того, что обычно делает цикл
Итерирование по словам
Выводит каждое слово в новой строке:
@echo off отключает вывод команд. @ перед командой отключает вывод данной команды
Этот пример необходимо записать в bat-файл и запустить файл. Если вводить цикл в командной строке, то он должен выглядеть слегка иначе:
FOR %a in (one two three) do @echo %a
Да, синтаксис переменной цикла зависит от того, вводим ли мы этот цикл в командной строке или он записан в файл. Если какой-то софт запускает команду, которую вы ему укажете, и вы хотите использовать в ней цикл, синтаксис зависит от того, каким образом этот софт передает команду командному интерпретатору. Это можно делать через командную строку или через стандартный ввод. В этих случаях используется один знак процента. Вариант с файлом мы уже пробовали в примере. Там используются два знака процента.
Цикл разбирает строку в скобках по тем же правилам, что параметры командной строки: строка в кавычках – это один параметр. Пример:
Выводит две строки:
Строки выводятся без кавычек, потому что использована переменная %%~a. %%a содержит кавычки.
Замена подстрок
Заменяет строчную букву C на заглавную. Выводит:
Выводит 2 символа, начиная с 5-го, в данном случае " ef ".
Условия
Ничего не выводит.
Если строки до и после знаков равенства совпадают с учетом регистра, то команда выполняется, иначе не выполняется. В обеих строках можно использовать переменные. При этом надо иметь ввиду, что в переменных может быть всё, что угодно, включая знаки равенства и пустые строки. От значений переменных будет зависеть синтаксическая правильность команды.
Вот такой способ проверить параметр командной строки работает и при отсутствии параметра, и если в нем спецсимволы:
if "%~1"=="help" echo This is a test script && exit /B
Оператор && - это один из способов выполнить несколько команд под условием. На самом деле это ленивое «и», т.е. если первая команда вернет ненулевой errorlevel, то вторая уже не выполнится.
Другой способ – скобки:
Как видите, со скобками можно использовать слово else.
Насчет скобок нужно помнить одну вещь. Условие или цикл с блоком команд в скобках – это одна команда. Значения переменных в ней подставляются один раз в самом начале.
То есть, нельзя внутри такого блока присвоить значение переменной и позже в том же блоке его использовать. Нельзя присвоить значение на одной итерации цикла и использовать на другой.
При таких сценариях приходится выносить код в подпрограммы.
Есть еще поздняя подстановка переменных. Ее надо включать командой SETLOCAL ENABLEDELAYEDEXPANSION , а вместо символа " % " использовать " ! ".
Преобразование параметров при подстановке
%~1 – первый параметр без кавычек. Как вы помните, параметр может быть указан либо в кавычках, либо без них, и кавычки, если они есть, будут и в переменной. От того, есть ли кавычки в переменной, зависит, будет ли содержащее ее выражение синтаксически правильным. Проверить наличие кавычек с помощью оператора if не получится, потому что в одном из двух случаев выполнение скрипта прервется из-за синтаксической ошибки. Однако, тильда перед именем переменной гарантирует, что кавычек на месте этой переменной не будет.
%~dp0 – полный путь к папке текущего bat-файла, без имени самого файла.
%~nx0 – имя и расширение текущего bat-файла, без пути
Поставив вместо нуля другую цифру, можно аналогичным образом разобрать путь, переданный скрипту через командную строку. Это также работает с переменными циклов, но не с переменными окружения.
Цикл по файлам или папкам
Следующая команда выводит список файлов в текущем каталоге:
FOR %%a in (*.*) do echo %%a
А так можно получить список папок:
FOR /D %%a in (*.*) do echo %%a
Параметр /R включает обход всех подкаталогов. При этом в переменной цикла полные пути:
FOR /R %%a in (*.*) do echo %%a
FOR /D /R %%a in (*.*) do echo %%a
Вместо " *.* " можно писать просто " * ". Результат абсолютно такой же: в обоих случаях выбираются файлы как с расширениями, так и без.
Читайте также: