How safe is the echo literal string "% I"?

How can I echo a string in a %Isafe manner, regardless of whether the string is echoin a loop for %I?

For example, on the command line ( cmd):

>>> rem // `echo` is outside of `for` scope, so this works:

>>> echo %I
%I

>>> rem // `echo` is inside of `for` scope, so `%I` is resolved:

>>> for %I in (.) do @echo %I
.

>>> rem // escaping does not help, `%I` is still resolved:

>>> for %I in (.) do @(echo ^%I & echo %^I & echo ^%^I & echo %%I)
.
.
.
%.

And in the batch file ...:

@echo off & rem // Here you need to double the `%` signs!
rem // `echo` is outside of `for` scope, so this works:
echo %%I & echo %%%%I
echo/
rem // `echo` is inside of `for` scope, so `%%I` is resolved:
for %%I in (.) do (echo %%I & echo %%%%I)
echo/
rem // escaping does not help, `%%I` is still resolved:
for %%I in (.) do (echo ^%%I & echo %%^I & echo ^%%^I & echo ^%^%I & echo ^%^%^I & echo ^%%^%%^I)

... result:

%I
%%I

.
%.

.
.
.
I
^I
%.

So, how do I modify the above approaches (both the cmdbatch file) to get an %Iecho?

+4
source share
1 answer

There are two ways to get around an unintended link extension for %I:

Deferred extension

In cmd:

>>> rem // Ensure that delayed expansion is enabled!

>>> set "STR=%I"

>>> echo !STR!
%I

>>> for %I in (.) do @echo !STR!
%I

In the batch file ...:

@echo off & rem // Here you need to double the `%` signs!
setlocal EnableDelayedExpansion
set "STR=%%I"
echo !STR!
for %%I in (.) do echo !STR!

set "STR=%%%%I"
echo !STR!
for %%I in (.) do echo !STR!
endlocal

... with the result:

%I
%I
%%I
%%I

, ; setlocal/endlocal.

:

for Loop

cmd:

>>> for %J in (%I) do @echo %J
%I

>>> for %J in (%I) do @for %I in (.) do @echo %J
%I

...:

@echo off & rem // Here you need to double the `%` signs!
for %%J in (%%I) do (
    echo %%J
    for %%I in (.) do echo %%J
)
for %%J in (%%%%I) do (
    echo %%J
    for %%I in (.) do echo %%J
)

... :

%I
%I
%%I
%%I

%%J, .

+3

Source: https://habr.com/ru/post/1665136/


All Articles