Home > Net >  Cmd or Batch - Setting Variable then echoing fails
Cmd or Batch - Setting Variable then echoing fails

Time:04-29

I found a GUI app on Github that I'm using to store command lines to run. The author is using the following syntax to take what I enter and use it in a cmd window -

I enter into his form -

set "test=four"

echo %test%

pause

He converts it to this and it fails to show the contents of the variable -

"C:\Windows\System32\cmd.exe" /Kset "test=four"&&echo %test%&&pause

The result is %test%, not the contents of the test variable, which is four.

If I run his command line in a cmd window myself, it also fails to get the var contents and shows %test%.

So why is this not working and I suggested to him to just copy what I entered into his form and do a paste into the cmd window he generates and run it. Can that be coded easily and is that the easiest fix?

CodePudding user response:

TL;DR: Use cmd /v:on /k (set "test=four" ^& echo !test! ^& pause)
Read How does the Windows Command Interpreter (CMD.EXE) parse scripts? for additional information about what's going on.


I want to preface this by saying that chaining commands to be on the same line is always a bad idea. You're allowed to run commands on multiple lines for a reason, and you should take advantage of this; it makes things easier to read and it makes the script behave better.

That said, there is a way to do this, but your code has multiple things keeping it from working.

First of all, && is meant for only running the second command when the first command succeeds. Neither cmd nor echo will ever fail, so you only need & here. echo %test% is running separately from the rest of your code because the way that the interpreter is reading your code, it thinks that you only want to run "C:\Windows\System32\cmd.exe" /Kset "test=four" and then run echo %test% once that comes back successfully. In order to run all three commands in the same instance of cmd, you need to use parentheses so that everything gets treated as a single command.

Additionally, in order to tell the interpreter that & isn't meant to be used to chain commands until the new cmd instance is running, you need to escape them with ^.

Finally, because you're trying to set and use a variable on the same line, the interpreter tries to replace %test% with its value when it first gets read in before the value has a chance to get set. To get around this, you need to enable delayed expansion by using the /V:on flag and then use !test! so that the variable doesn't get expanded until execution time.

  • Related