0

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?

tyee
  • 317
  • 1
  • 3
  • 14
  • Why are you trying to run three separate commands in a single line? There's no good reason to ever do this, and it causes more problems than it solves 100% of the time. – SomethingDark Apr 25 '22 at 16:50
  • You could do it like this: ```"C:\Windows\System32\cmd.exe" /D /K "Set "test=four" & Call Echo(%%test%% & Pause"```. The correct way to do this would be to use delayed expansion ```"C:\Windows\System32\cmd.exe" /D /V /K "Set "test=four" & Echo(!test!& Pause"```. You should not need, in this case, to use conditional _(double)_ ampersands, and the cmd.exe `/C` or `/K` argument should itself be enclosed within double quotes. – Compo Apr 25 '22 at 19:35

1 Answers1

1

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.

SomethingDark
  • 13,229
  • 5
  • 50
  • 55
  • Thanks. I will let the author know of this answer. – tyee Apr 26 '22 at 02:54
  • @tyee - If it's on Github, you can just submit a pull request. As for here, if this answer solved your problem, please mark it as solved by clicking the check mark. – SomethingDark Apr 26 '22 at 03:19
  • 1
    The author decided to copy the commands to a .bat file. It now works well. – tyee Apr 29 '22 at 01:32