Не объявляется переменная

Foxik

Новый пользователь
Сообщения
41
Реакции
26
где ошибка в сценарии? Почему не объявляются переменные cnt и summ?
CMD/BATCH:
@echo off
rem SetLocal EnableExtensions EnableDelayedExpansion
Echo List Local users:

for /f "usebackq tokens=2 delims==" %%a in (`WMIC UserAccount Where "LocalAccount=True" Get Name /Format:List`) do (

set /a cnt+=1
set "User_%cnt%=%%a"
set "summ=%summ%%cnt%"
ECHO %cnt%. %%a
)
echo %summ%
 
Последнее редактирование модератором:
Способ 1.
1) *Вам нужно заменить %cnt% на !cnt!
2) снять с комментария 2-ю строку с директивами, т.к. EnableDelayedExpansion включает режим отложенного раскрытия переменных (разрешение на использование тех самых знаков !!)
3) Что Вы хотите получить в переменной summ ?

* Все команды, выполняемые внутри блока (цикл, скобки или однострочные команды) изменяют переменные среды только после выхода из данного блока.
Чтобы получить актуальное значение переменной внутри этого же блока, нужно использовать механизм, указанный мною в пп.1,2.
При этом не важно, где было произведено изменение значения переменной (внутри блока, через переход в подпрограмму или внешним окружением (например, псевдослучайное число, текущая дата/время). Все они при входе в блок команд запоминаются и "замораживаются".

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

Способ 2.
Раскрывать значение переменной в другом процессе CMD:
1) заменить тело цикла на код с использованием команды SET (при этом знаки % следует удвоить):

CMD/BATCH:
set /a cnt+=1
call set "User_%%cnt%%=%%a"
call set "summ=%%summ%%%%cnt%%"&rem здесь что писать не знаю; жду пояснения.
call ECHO %%cnt%%. %%a
 
Последнее редактирование:
Спасибо, разобрался, все поправил, все работает...
Вот итог:
CMD/BATCH:
@echo off
Setlocal EnableDelayedExpansion
Echo List Local users:
for /f "usebackq tokens=2 delims==" %%a in (`WMIC UserAccount Where "LocalAccount=True" Get Name /Format:List`) do (
set /a cnt+=1
set "User_!cnt!=%%a"
set "summ=!summ!!cnt!"
ECHO !cnt!. %%a
)
Choice /C %summ% /M "choice users:"

Переменная summ нужна была для параметра команды CHOICE... хотя теперь это и так понятно:rolleyes:
Теперь еще кто-нибудь, также доходчево объяснил бы про EnableExtensions:whistle:
 
Последнее редактирование модератором:
Переменная summ нужна была для параметра команды CHOICE... хотя теперь это и так понятно
Оригинально придумано :)
Теперь еще кто-нибудь, также доходчево объяснил бы про EnableExtensions
https://safezone.cc/threads/cmd-setlocal-i-rasshirennaja-obrabotka-komand.22629/Другими словами, если я сделаю вот так:
Код:
reg add "HKCU\Software\Microsoft\Command Processor" /v EnableExtensions /t REG_DWORD /d 0 /f
Ваш последний скрипт перестанет работать ;)
 
Последнее редактирование:
Другими словами, если я сделаю вот так:
Код (text):
reg add "HKCU\Software\Microsoft\Command Processor" /v EnableExtensions /t REG_DWORD /d 0 /f

Ваш последний скрипт перестанет работать
Не беда. => cmd.exe /X Enable
 
Точнее /X:ON или /E:ON
или посмотреть внимательно на Ваш первый скрипт.
 
Вот еще вариант без Setlocal:
CMD/BATCH:
@echo off
Echo List Local users:
for /f "usebackq tokens=2 delims==" %%a in (`WMIC UserAccount Where "LocalAccount=True" Get Name /Format:List`) do CALL:CREATE_CMD %%a
Choice /C %summ% /M "choice users:"
call set choi_usr=%%user_%errorlevel%%%

echo %choi_usr%
pause

goto:eof
:CREATE_CMD
set /a cnt+=1
set User_%cnt%=%1
set summ=%summ%%cnt%
ECHO %cnt%. %1
 
Последнее редактирование модератором:
Foxik, да можно и так. Но для небольших конструкций слишком "расточительно" по объему кода.
Кроме того, если Вас заинтересует скорость работы этих 3-х вариантов, то они соотносятся примерно так:

1) точка отсчета затраченного времени - раскрытие значения через %%
2) через !! ~ 2,5 раза медленнее
3) через подпрограмму ~ 42 раза медленнее
4) через call set ~ 60 раз медленнее

Для конкретного кода, конечно, не имеет значения, а вот для пакетной обработки OVER 100 строк уже чувствуется (особенно на слабых машинах).

P.S. Саму команду SetLocal указываю всегда, ибо после выхода из батника все измененные переменные окружения автоматически обнуляются
(либо это можно сделать еще раньше - командой EndLocal)
или посмотреть внимательно на Ваш первый скрипт.
т.е. Вы можете указывать SetLocal EnableExtensions всегда и тогда Ваш скрипт не будет зависеть от указанного мною в реестре твика.
 
Последнее редактирование:
Назад
Сверху Снизу