Мусорное эхо после set / a в макросе - PullRequest
2 голосов
/ 08 февраля 2020

У меня проблема с моим пользовательским макросом, и я пока не знаю, как ее решить. Я надеюсь, что кто-то здесь знает ответ, и моя жизнь станет более яркой после его или ее полезного совета. Пример сценария ms-dos:

@echo off
setlocal enabledelayedexpansion

set @test_macro=^
 set /a "test_num1=1"^&set /a "test_num2=1"^&^
 (for /L %%n in (1,1,10) do (set /a "test_num1+=%%n"^&set /a "test_num2*=%%n"))^>nul^&^
 echo ^^^!test_num1^^^! ^^^!test_num2^^^!

set @test_of_test_macro=for /F "usebackq tokens=*" %%i in (`"cmd /d /q /e:on /v:on /r ^!@test_macro^!"`) do echo %%i

echo Usual call, gives expected output "56" ^& "3628800":
%@test_macro%

echo Call from another macro, gives expected output "56" ^& "3628800", but followed by garbage "11":
%@test_of_test_macro%

Дает следующий вывод:

Usual call, gives expected output "56" & "3628800":
56 3628800
Call from another macro, gives expected output "56" & "3628800", but followed by garbage "11":
1156 3628800

Это поведение erroneus изменяется в зависимости от количества инициализированных числовых переменных c и в порядке их инициализации, но приведенный выше сценарий дает представление о проблеме.

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

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 08 февраля 2020

Использование вложенных макросов всегда немного сложно, особенно если вы пытаетесь выполнить их с помощью cmd /V:on.

Обрабатывать (экранировать) все фазы расширения, даже не видя, что происходит, немного сложно.

В вашем случае echo ^^^!test_num1^^^! ^^^!test_num2^^^! отлично работает при прямом вызове @test_macro, но когда вы попробовали это с @test_of_test_macro, переменные раскрываются до остальной части кода даже запускается.
Проверьте его, установив обе переменные перед запуском макроса

set test_num1=HELLO
set test_num2=WORLD
%@test_of_test_macro%

В результате вы получите 11HELLO WORLD!

Но использование cmd для запуска макроса плохая идея, потому что вы теряете преимущество макросов, они быстрые! Но начиная их с cmd.exe штраф намного выше, чем просто вызов функции.

0 голосов
/ 09 февраля 2020

Спасибо за ваши ответы, в частности Mofi: в этом случае лучше вообще не использовать арифметическое c назначение. Я изменил выборку, чтобы использовать обратный порядок звонков, у меня это сработало:

@echo off
setlocal ENABLEEXTENSIONS enabledelayedexpansion

set @test_macro=^
 set "test_num1=1"^&set "test_num2=1"^&^
 (for /L %%n in (1,1,10) do (set /a "test_num1+=%%n"^&set /a "test_num2*=%%n"))^>nul^&^
 echo ^^^!test_num1^^^! ^^^!test_num2^^^!^&^
 set "test_num1="^&set "test_num2="

set @test_of_test_macro=for /F "usebackq tokens=*" %%i in (`cmd /d /q /e:on /v:on /r "^!@test_macro^!"`) do echo %%i

echo Call from another macro, gives expected output "56" ^& "3628800" (without any "11"):
%@test_of_test_macro%

echo Usual call, gives expected output "56" ^& "3628800":
%@test_macro%
0 голосов
/ 08 февраля 2020

Упс, вопрос решен. Достаточно добавить ^> NUL после каждой инициализации числовой переменной c:

set /a "test_num1=1"^&set /a "test_num2=1"^>NUL^&^

Это решает эту проблему. Спасибо

...