Как отобразить пакетные команды без выполнения? - PullRequest
1 голос
/ 26 марта 2020

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

Вот пример:

@echo off&&setlocal enabledelayedexpansion
echo/teach me a question to answer.
set/p q=
echo(>>%~f0
echo/:%q: =%>>%~f0
cls
echo/teach me three ways to answer it.
set/p a1=
set/p a2=
set/p a3=
echo/set a[0]=%a1%>>%~f0
echo/set a[1]=%a2%>>%~f0
echo/set a[2]=%a3%>>%~f0
echo/"set/a ax=%random% %%3&&set aa=!a[%ax%]!">>%~f0
echo/"echo %aa%">>%~f0

Но я получаю следующее:

:howareyou?
a[0]=good
a[1]=fine
a[2]=well
"set/a ax=24793 %3&&set aa="
"echo "

Возможно чтобы получить

set/a ax=%random% %%3&&set aa=!a[%ax%]!
echo %aa%

в точности как есть?

Ответы [ 2 ]

1 голос
/ 26 марта 2020

В этом коде есть две проблемы.

Прежде всего, чтобы ответить на ваш вопрос:

Как отобразить именно то, что я ввожу?

В пакетном случае ответ всегда сложнее, чем вы думаете . В случае echo кавычки на самом деле не изменяют способ интерпретации % и !, но они также отражаются, что сейчас плохо.

Вместо этого, избегайте % путем дублирования , &, поставив ^, и !, поставив два ^ с перед ним [ref] :

echo set/a ax=%%random%% %%%% 3^&^&set aa=^^!a[%%ax%%]^^! >>%~f0
echo echo %%aa%% >>%~f0

Теперь вы можете видеть, что все отображается правильно, но повторяющийся код все равно не будет работать.

Почему?

Вторая проблема заключается в &&: процентные переменные (%var%) будут подставлены перед вычислением строки или группы команд (команды, заключенные в скобки).

То есть, поскольку set /a и set находятся в одной строке, значение %ax% будет подставлено перед set /a устанавливает это. Этого можно избежать, используя мощь отложенного расширения и его синтаксис !ax!, но в этом случае это невозможно, поскольку к нему обращаются внутри доступа другой переменной.

Итак, вместо этого делайте то, что нужно && сделал бы иначе:

set/a ax=%random% %% 3
if %errorlevel% GTR 0 set aa=^^!a[%%ax%%]^^!

Наконец, вы получите что-то вроде:

echo set/a ax=%%random%% %%%% 3 >>%~f0
echo if %%errorlevel%% GTR 0 set aa=^^!a[%%ax%%]^^! >>%~f0
echo echo %%aa%% >>%~f0
0 голосов
/ 26 марта 2020

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

@echo off & setlocal DisableDelayedExpansion Set "/Ex=^!"

и использование:

Echo(Set "Answer=%/Ex%Answer[%%RandAnswer%%]%/Ex%">>Bot.bat

Настоятельно рекомендуем прочитать здесь, чтобы понять, как анализируется командная строка и почему это работает.

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