Как показать, что пользователь набрал в этой команде? - PullRequest
0 голосов
/ 28 февраля 2019

пожалуйста, помогите!Я искал ответ по всему интернету.

Вот мой код:

@echo off
title var test
:question
set a1=This
set a2=Is
set a3=a
set a4=Var
set a5=Test
choice /c 12345 /m "press a number"
if errorlevel=5 set num=5&goto answer
if errorlevel=4 set num=4&goto answer
if errorlevel=3 set num=3&goto answer
if errorlevel=2 set num=2&goto answer
if errorlevel=1 set num=1&goto answer
:answer
echo now change the answer.
set /p a%num%=
FOR /F "tokens=1-6" %%1 IN ("%a1% %a2% %a3% %a4% %a5% a%num%") DO echo %%1 %%2 %%4 %%5.&echo You typed=%%6
pause
goto question

Как видите, я заставил пользователя выбрать число от 1 до 5, чтобы изменить конкретное слово,Но когда я пытаюсь показать тот же код, чтобы показать, что он набрал, не работает: (

1 Ответ

0 голосов
/ 28 февраля 2019

Переменные среды никогда не должны начинаться с цифры, поэтому следует избегать использования цифр для переменных цикла.Запустите в окне командной строки call /?, и вывод является справкой для этой команды, объясняющей, как на аргументы пакетного файла можно ссылаться с помощью %0, %1, %2, ..., которая объясняет, почему переменные среды с цифрой в качестве первогосимвольные и циклические переменные с цифрой вообще не годятся, даже если значение a%num% в наборе FOR не ссылается на значение переменной окружения a1 или a2 или a3 или a4 или a5.Это просто имя переменной среды.Цикл for совсем не нужен.

@echo off
title var test
:question
set "a1=This"
set "a2=Is"
set "a3=a"
set "a4=Var"
set "a5=Test"
%SystemRoot%\System32\choice.exe /C 12345E /N /M "Press a number in range 1-5 or E for exit: "
if errorlevel 6 goto :EOF
set "num=%ERRORLEVEL%"
set /P "a%num%=Now change the answer: "
echo %a1% %a2% %a3% %a4% %a5%.
call echo You typed: %%a%num%%%
pause
goto question

Командная строка call echo You typed: %%a%num%%% анализируется командным процессором Windows перед выполнением командной строки с номером 3, введенным в call echo You typed: %a3%.Эта командная строка анализируется второй раз из-за команды call, в результате которой %a3% заменяется значением переменной среды a3, поэтому echo выводит ожидаемую строку.

Это также возможнозаменить call echo You typed: %%a%num%%% на

setlocal EnableDelayedExpansion
echo You typed: !a%num%!
endlocal

Использование отложенного расширения переменной среды также приводит к двойному анализу командной строки перед выполнением команды echo.Подробнее см. Как синтаксический анализ сценариев интерпретатора команд Windows (CMD.EXE)?

Прочтите также этот ответ , чтобы узнать подробнее о командах SETLOCAL и ENDLOCAL .

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

echo %a1% %a2% %a3% %a4% %a5%.
call echo You typed: %%a%num%%%

Например, если пользователь вводит номер 1 и в следующем приглашении вводит:

Your user name is:& setlocal EnableDelayedExpansion & echo !UserName!& endlocal & rem

Затем пакетный файл делает что-то совершенно иное, чем предназначенное для него, и выводит имя учетной записи пользователя.

Безопасным будет код пакета:

@echo off
title var test
setlocal EnableExtensions DisableDelayedExpansion
:question
set "a1=This"
set "a2=Is"
set "a3=a"
set "a4=Var"
set "a5=Test"
%SystemRoot%\System32\choice.exe /C 12345E /N /M "Press a number in range 1-5 or E for exit: "
if errorlevel 6 goto :EOF
set "num=%ERRORLEVEL%"
set /P "a%num%=Now change the answer: "
setlocal EnableDelayedExpansion
echo !a1! !a2! !a3! !a4! !a5!.
echo You typed: !a%num%!
endlocal
pause
goto question

Теперь строка пользовательского ввода больше не может изменять командные строки, выполняемые процессором команд Windows.

Решение с бесполезным FOR цикл будет выглядеть так:

setlocal EnableDelayedExpansion
for /F tokens^=1-6^ eol^= %%A in ("!a1! !a2! !a3! !a4! !a5! !a%num%!") do echo %%A %%B %%C %%D %%E.&echo You typed: %%F
endlocal

eol= необходимо вывести все правильно, даже если использовать ввод числа 1 и следующую строку, начинающуюся с точки с запятой.Строка опций FOR не может быть заключена в двойные кавычки в этом случае, например "tokens=1-6 eol=", потому что это определит " как символ конца строки, и ничего не выводится, если пользователь вводит число 1 и вводит следующеестрока, начинающаяся с ".Знак равенства и пробел должны быть экранированы с ^, чтобы интерпретироваться как буквенные символы с помощью cmd.exe при двойном анализе всей командной строки for перед выполнением команды for.

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

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