2

When I try to make a variable, sometimes it won't recall when surrounded with %. An example is

@echo off
set firstvar= <o
set secondvar= ^. .^
echo.
echo %firstvar%
echo %secondvar%
pause

I'm wanting it to show up as

 <o
^. .^

but I get

The system cannot find the file specified.
ECHO is off.
 . .echo.
Press any key to continue . . .

I'm really confused by this and I can't seem to fix it. I've narrowed down the problem to be something about the rules of assigning variables, and I'm guessing that the <o is being viewed as HTML or a website or something. I'm really confused with the second line though, why does it say ECHO is off? Why . .echo.? Any help would be appreciated, thank you.

PieMan3259
  • 21
  • 1

2 Answers2

1

First, read the answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? for an explanation why it is advisable to use the syntax set "variable=value" on assigning something to an environment variable.

Second, read the Microsoft article about Using Command Redirection Operators for an explanation of meaning of < in a Windows command line.

Third, caret character ^ is interpreted by Windows command interpreter as escape character like the backslash character \ by many programming and scripting languages.

So the batch code with immediate environment variable expansion should be coded as:

@echo off
set "firstvar= ^<o"
set "secondvar= ^^. .^^"
echo/
echo %firstvar%
echo %secondvar%
echo Okay!

The strings to output are easier to code on using delayed expansion:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "firstvar= <o"
set "secondvar= ^. .^"
echo/
echo !firstvar!
echo !secondvar!
echo Okay^^!
endlocal

^ and < must not be escaped inside a double quoted string and delayed expansion is used on outputting the strings of the environment variables.

Note 1: The two environment variables firstvar and secondvar do not exist anymore after the line with endlocal which is usually the last line in a batch file on using setlocal. Read this answer for details about the commands SETLOCAL and ENDLOCAL.

Note 2: A percent sign % must be escaped with another % and not with ^ to be interpreted as literal percent sign and not as begin/end of an environment variable reference expanded during preprocessing of a command line or an entire command block starting with ( and ending with matching ) before running a command line.

Note 3: Any string including directory/file names containing an exclamation mark ! is interpreted different on having delayed expansion enabled. Then the exclamation mark is interpreted as begin/end of an environment variable reference expanded delayed after preprocessing a command line/block. ! must be escaped with two ^ on delayed expansion being enabled to be interpreted as literal character. The command line with ^^! changes to just ^! on first parsing it by Windows command processor. The command line changes to literally interpreted ! on second parsing of the command line because of enabled delayed expansion.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • cmd /? ... Windows command interpreter
  • echo /?
  • endlocal /?
  • set /?
  • setlocal /?

And read also DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/ why it is better to use echo/ instead of echo. to output an empty line.

Last read also Debugging a batch file for instructions how to see what the command interpreter really executes after preprocessing each command line/block.

See also: How does the Windows Command Interpreter (CMD.EXE) parse scripts?

Mofi
  • 46,139
  • 17
  • 80
  • 143
0

The caret ^ is the escape symbol, to echo it literally you have to double it ^^ once for every processing step (setting/echoing).
The redirecting/piping symbols <|> have to be escaped with a ^ caret.
If a string/variable to echo evaluates to nothing echo returns the status.
To avoid this use a different delimiter sign instead of a space \/(:; etc.

@echo off
set firstvar=  ^^^<o
set secondvar= ^^^^. .^^^^
echo.
echo:%firstvar%
echo:%secondvar%
pause