Set and print content of environment variable in cmd.exe subshell?

7,080

Solution 1

Why does this happen?

The %OPERATION% is expanded (Phase 1) before the variable has been set (Phase 7).

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

Processing a line of code in a batch file involves multiple phases.

Here is a brief overview of the various phases:

Phase 0) Read Line:

Phase 1) Percent Expansion:

Phase 1.5) Remove : Remove all Carriage Return (0x0D) characters

Phase 2) Process special characters, tokenize, and build a cached command block: This is a complex process that is affected by things such as quotes, special characters, token delimiters, and caret escapes.

Phase 3) Echo the parsed command(s) Only if the command block did not begin with @, and ECHO was ON at the start of the preceding step.

Phase 4) FOR %X variable expansion: Only if a FOR command is active and the commands after DO are being processed.

Phase 5) Delayed Expansion: Only if delayed expansion is enabled

Phase 5.3) Pipe processing: Only if commands are on either side of a pipe

Phase 5.5) Execute Redirection:

Phase 6) CALL processing/Caret doubling: Only if the command token is CALL

Phase 7) Execute: The command is executed

Solution 2

How can I set an environment variable, and then print it with echo in a single line, in a cmd.exe subshell?

To enable neccessary delayed expansion in a cmd subshell you'll have to use the /V:ON switch of cmd.exe and use an ! exclamation mark instead of the % percent sign.

> cmd /V:ON /C "SET OPERATION=NEW&echo [!OPERATION!]"
[NEW]

Just a reminder
The trailing space in your original set will be part of the variable content:

> cmd /V:ON /C "SET OPERATION=NEW &echo [!OPERATION!]"
[NEW ]
Share:
7,080

Related videos on Youtube

sdbbs
Author by

sdbbs

Updated on September 18, 2022

Comments

  • sdbbs
    sdbbs over 1 year

    Consider this example, where I start a new "sub" instance of cmd.exe, and then try to set a new environment variable in it, and then check if it has the proper value set (this is in cmd.exe of Windows 10):

    >cmd /c "SET OPERATION=NEW & SET O"
    OneDrive=C:\Users\user\OneDrive
    OPERATION=NEW
    OS=Windows_NT
    

    So, as noted in https://superuser.com/a/776506/688965 - by doing SET O I would "display all variables that begin with the letter 'O'", and indeed, it shows that an environment variable OPERATION exists, and its value is NEW. So far, so good.

    However, if I try to print the environment value instead, it does not expand:

    >cmd /c "SET OPERATION=NEW & echo %OPERATION%"
    %OPERATION%
    

    ... however, if I try to expand any other environment variable, it works ?!:

    >cmd /c "SET OPERATION=NEW & echo %OS%"
    Windows_NT
    

    Why does this happen? How can I set an environment variable, and then print it with echo in a single line, in a cmd.exe subshell?