Форум программистов, компьютерный форум, киберфорум
Batch (CMD/BAT)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.90/403: Рейтинг темы: голосов - 403, средняя оценка - 4.90
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16

SetLocal и расширенная обработка команд в Windows Batch [Статья]

10.05.2013, 21:38. Показов 81666. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
SetLocal и расширенная обработка команд

Часто встречали такую конструкцию ?
Bash
1
SetLocal EnableExtensions EnableDelayedExpansion
По своей сути она состоит из 3 совмещенных частей:

Bash
1
2
3
SetLocal &:: Локализация переменных
SetLocal EnableExtensions &:: Использование дополнительных ключей
SetLocal EnableDelayedExpansion &:: Раскрытие переменных через знаки (!)
SetLocal

Что делает?
SetLocal - означает, что все переменные, объявленные внутри Batch-файла, будут локальными и после выхода из него обнуляться.
Это также оберегает от случаев, когда Вы забываете задавать начальное значение переменной.

По-умолчанию, значение переменной при инициализации
для строкового типа = пустой строке,
для числового типа = 0.
Типы переменных.

Если Вы запускаете Batch-файл
- из CMD.exe (ПУСК -> Выполнить -> CMD -> {Enter})
- один Batch-файл из другого
то при повторном запуске без команды SetLocal в переменных останутся старые значения.

Область видимости переменной, заданной командой Set, является текущая среда интерпретатора, если батник запущен через нее (CMD.exe) (и внутри нет команды локализации SetLocal), или сессия самого батника, если двойным кликом по нему.
Цитата Сообщение от Smitis Посмотреть сообщение
А также дочерние процессы, запущенный после того, как переменная установлена.
Как задается?
Bash
1
SetLocal
Переменные, использованные после команды SetLocal, можно обнулить принудительно еще до выхода из Batch-файла командой:
Bash
1
EndLocal
EndLocal и знак & (амперсанд)*


Конструкция вида:
Bash
1
2
3
SetLocal
Set B=1
EndLocal& Set A=%B%
Позволяет обнулить переменную B, при этом в однострочной команде после EndLocal
переменная раскрываемая через % и все еще будет содержать старое значение, поэтому может быть "переброшена" через локаль.

В конструкции вида:
Bash
1
2
3
setLocal EnableDelayedExpansion
Set B=1
EndLocal& Set A=!B!
переменная A получит актуальное (обнуленное) значение переменной B,
поэтому способ "переброса" значения через локаль невозможно использовать внутри циклов.


Extensions - режим расширенной обработки команд.

Что делает?
Позволяет использовать дополнительные ключи встроенных команд.

Где используется?
Откройте справку по командам, например,
For /?
Set /?
Там в первых 10 строках найдете выражение:
"Если включена расширенная обработка команд... то можно использовать еще и такие ключи..."
chdir /?
"Если включена расширенная обработка команд... в таком случае поведение команды изменяется" (касается пробелов в пути).
...

Как включается?
1) Задается командой
Bash
1
SetLocal EnableExtensions
EnableExtensions - обычно включена в системе по-умолчанию.
Но может быть выключена принудительно через реестр, а также по-умолчанию, выключена в некоторых старых ОС.
http://technet.microsoft.com/e... 59665.aspx
Перенаправить поток ошибок программы в переменную
Поэтому, ее желательно включать во все скрипты.

2) Через реестр (выше по ссылкам).
3) Через ключи CMD.exe, если бат-файл или команда запускается через него, а не напрямую.
Метод может использоваться в однострочных командах, а также методах Shell других ЯП.
Пример:
Bash
1
cmd /E:ON /C Commands
где под Commands подразумевается путь и имя к командному файлу (bat, cmd), цикл, команда, или перечень команд, составленных по правилам формирования однострочных команд Batch.

Может быть отключена командой:
Bash
1
SetLocal DisableExtensions
Практическая польза от отключения, как мне известно, никакой.

DelayedExpansion - режим отложенного расширения переменных среды.

Что делает?
EnableDelayedExpansion - означает возможность использовать восклицательные знаки (!variable!) для раскрытия значения переменной.

Цитата Сообщение от Elroir
В обычном случае, чтобы узнать значение переменной окружения, надо воспользоваться конструкцией %переменная%. Однако, если значение переменной меняется внутри цикла и читается там же, то для корректной работы батника, нужно использовать команду setlocal enabledelayedexpansion и вместо символа "%", использовать символ "!". Иначе, значение переменной в цикле будет всегда одним и тем же - таким, каким было до входа в цикл.
Обычно переменные раскрываются через знак %.
"Раскрывается" - означает, что мы получаем значение, которое хранит переменная.

Пример:
Bash
1
2
3
4
:: Инициализируем переменную и задаем ей значение "Кот"
set Animal=Кот
:: Выводим на экран значение переменной Animal
echo %Animal%
Необходимость использовать знаки (!) возникает:
  • внутри цикла
  • под скобками
  • в однострочной команде
*Здесь и далее под конструкцией подразумевается один из указанных выше вариантов.

Если Вы измените значение переменной внутри конструкции,
раскрывая переменную через %, Вы получите ее старое значение (присвоенное до входа в эту конструкцию).

Новое (актуальное) значение переменной можно получить:
  • раскрыв переменную через знаки (!)
  • временно выйдя за пределы конструкции (например, командой Call)
  • после выхода из данной конструкции (ее завершения)


Как включить возможность использовать (!):
По-умолчанию, данный режим выключен.

Включить можно:
1) командой:
Bash
1
SetLocal EnableDelayedExpansion
2) через реестр (на постоянной основе - пользоваться пп.1,3 будет не нужно, но будет работать только на Вашей машине.)
http://technet.microsoft.com/e... 57361.aspx

3) запуском batch-файла или команд(ы) через специальный ключ CMD.exe:
Пример:
Bash
1
cmd /V:ON /C Commands
где под Commands подразумевается путь и имя к командному файлу (bat, cmd), цикл, команда, или перечень команд, составленных по правилам формирования однострочных команд Batch.

Почему бы всегда не использовать этот метод вместо % ?

1) раскрытие переменной через % быстрее, чем через !
Оптимизация кода

2) при чтении данных из файла, в содержимом которого есть знаки ! и последующей записью или выводом на экран
этой информации знаки ! "глотаются". Поэтому еще иногда используется команда отключения данного режима:
Bash
1
SetLocal DisableDelayedExpansion
3) Когда анализируешь свой же код, удобно понимать логику работы своего алгоритма: если видишь % под циклом, то сразу понятно, что значение этой переменной под циклом не изменяется, а если и изменяется, то в этой же конструкции новое значение не используется.


Примеры практического использования:


1) Цикл:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@echo off
SetLocal EnableExtensions EnableDelayedExpansion
 
:: Читаем файл example.txt
:: Заводим счетчик строк count
:: 5-ю строку файла выводим на экран
 
set count=0
 
For /F "delims=" %%a in (example.txt) do (
  set /A count+=1
  if !count!==5 echo %%a
  echo В этом месте значение count всегда будет = 0. Count = %count%
  echo А здесь мы получим актуальное значение Count = !Count!
)
2) Просто под скобками:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@echo off
SetLocal EnableDelayedExpansion
(
  rem Присвоим значение переменной
  set variable=text
 
  echo Формируем
  echo несколько
  echo строк
  echo текстового
  echo файла
 
  echo Здесь ничего не получим. Перед скобками переменной не было присвоено значение.
  echo.%variable%
 
  echo Здесь получим актуальное значение
  echo !variable!
) >> example.txt
3) В однострочных командах:

Bash
1
2
3
4
5
6
7
8
@echo off
SetLocal EnableDelayedExpansion
 
set st1=staraya stroka
set st1=novaya stroka& echo Здесь получим старую строку %st1%
 
set st2=staraya stroka
set st2=novaya stroka& echo Здесь получим новую строку !st2!



Ремарка:
Принцип раскрытия переменных влияет также на изменяемые глобальные переменные, например,
time и date, которые постоянно обновляются и отображают дату и время.

После входа в конструкцию эти переменные "замораживаются".
Чтобы получить актуальную дату/время необходимо раскрытие через знаки (!):

Bash
1
echo !date! !time!
11
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.05.2013, 21:38
Ответы с готовыми решениями:

Батник переименования файлов и "SetLocal и расширенная обработка команд"
Здравствуйте. пишу код переименования файлов. не могу разобраться с "SetLocal EnableExtensions EnableDelayedExpansion". ниже...

Можно ли организовать выполнение команд Telnet с использованием VBS и Batch?
Есть компьютер на винде 7 и есть компьютер на линуксе. Нужно проверить работает ли процесс в линукс системе и в случае чего перезапустить....

Windows 7 Домашняя расширенная
Как убрать надпись "Windows 7 Домашняя расширенная" при приветсвии

4
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
17.02.2016, 20:04  [ТС]
Практические примеры к SetLocal EnableDelayedExpansion от ComSpec:

Комментарии в bat-файле
1
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
18.10.2017, 14:17  [ТС]
Поддержка режимов EnableExtensions и DelayedExpansion в старых версиях ОС.
0
5 / 5 / 0
Регистрация: 24.11.2014
Сообщений: 51
04.12.2023, 18:39
Что-то я запутался с EnableDelayedExpansion. При использовании SetLocal EnableDelayedExpansion как лучше выключить DelayedExpansion? Обычно, просто используют EndLocal. Но, тогда зачем имеется конструкция SetLocal DisableDelayedExpansion? И ещё, команда EndLocal DisableDelayedExpansion (или EndLocal EnableDelayedExpansion) не вызывает ошибок, хотя в документации о ней не сказано (как в справке самой команды, так и на сайте M$). Как это, вообще, понимать?
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18030 / 7733 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
04.12.2023, 18:51  [ТС]
Andrey_Vladi-ch, запустите и увидите разницу:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
@echo off
 
set i=1
 
SetLocal EnableDelayedExpansion
  set i=2
  SetLocal DisableDelayedExpansion
    echo i=%i%
  EndLocal
EndLocal
echo i=%i%
 
pause
DisableDelayedExpansion ещё используется в начале скрипта, чтобы убедиться, что он работает в режиме с отключенным режимом отложенного расширения переменных среды. В системе может быть настроено автоматическое его включение, например, через ключ реестра HKCU\Software\Microsoft\Command Processor\AutoRun или если кто-то специально запускает скрипт через cmd.exe /v:on

Цитата Сообщение от Andrey_Vladi-ch Посмотреть сообщение
Code
1
EndLocal EnableDelayedExpansion
Такого параметра нет. Вы можете напечатать рядом с EndLocal что угодно. У нее просто отсутствует проверка аргумента.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
04.12.2023, 18:51
Помогаю со студенческими работами здесь

windows 7 домашняя расширенная, ошибки
Здравствуйте. У меня вот какая проблема: windows запускается без проблем, но никакие программы не работают, даже элементарно word не...

Активация windows 7 домашняя расширенная
Помогите с активацией windows 7!скачал ключи перепробовал все- и не один не пошёл!Пишет: Введённый ключ заблокирован Microsoft. Если кто...

Windows 7 домашняя расширенная не подключается к инету?
В сети 2 домена на одном из них интернет, ноут подключается к сети через рабочую группу и видит часть компьютеров в сети, которые я так...

[Статья] Windows 10 Creators Update: что нового в Bash/WSL и Windows Console
Когда вышел Windows 10 Anniversary Update (AU), подсистема Windows Subsystem for Linux (WSL) была ещё далека от завершения и страдала от...

Где можно скачать MSDN образ версии ОС Windows Домашняя Расширенная?
Здравствуйте, подскажите пожалуйста, где можно скачать MSDN образ версии ОС Windows Домашняя Расширенная?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
PowerShell Snippets
iNNOKENTIY21 11.11.2025
Модуль PowerShell 5. 1+ : Snippets. psm1 У меня модуль расположен в пользовательской папке модулей, по умолчанию: \Documents\WindowsPowerShell\Modules\Snippets\ А в самом низу файла-профиля. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru