Windows command line: using a variable set on a single line single line

Well, I found out that you can use & or && to combine several commands into one line, but it seems that set variables are actually not available for interpolation on one line:

 C:\Users\Andrew>set foo=hello, world!&& echo %foo% %foo% C:\Users\Andrew>echo %foo% hello, world! 

Why can't I do this job, and is there a way to get it to work on the same line?

The reason I need a single liner is because the external program I'm working with accepts a single command as a pre-launch, and of course I need to run several commands.


Preventive protection

  • " hello, world! must be surrounded in double quotes!" Actually, it looks like this saves literal double quotes in a variable that I don't want, like

     C:\Users\Andrew>set bar="hello, world!"&& echo %bar% %bar% C:\Users\Andrew>echo %bar% "hello, world!" 
  • "There must be a space before && !" Actually, it looks like this saves the finite space in a variable that I don't want, like

     C:\Users\Andrew>set bar="hello, world!"&& echo %bar% %bar% C:\Users\Andrew>echo %bar% "hello, world!" 
  • "Both!" >: (

     C:\Users\Andrew>set mu="hello, world!" && echo %mu% %mu% C:\Users\Andrew>echo (%mu%) ("hello, world!" ) 
+7
syntax windows windows-7 cmd batch-file
source share
3 answers

You can do this on the same line, but I would recommend using a batch file like preHook.bat.

Like one liner

 set "mu=hello, world!" && call echo %^mu% 

At first you can see that the quotation marks are different from yours.


That's why:

 set test1="quotes" set "test2=no quotes" with comment 

In the first test, quotation marks will be part of the variable test1 , as well as all characters after the last quote.

In the second test, it uses the extended syntax of the SET command.
Thus, the content will be no quotes , since only the content of the last quote is used; the rest will be deleted.

To reflect the contents of a variable, I use call echo %^mu% , since a percentage extension will expand it when the string is parsed, before executing any of the commands.

But the call command will be executed later, and it will restart the parser, which when used on the command line uses different extension rules than the batch parser: an empty variable (in this case %^mu% , for the first time) remains unchanged in the line; but in the next phase of the syntax, the carriage ^ will be deleted.

In your case, call echo %mu% will also work, but only when mu always empty. The carriage option also works when mu has content before the line is executed.

Read more about the parser in SO: How is the Windows Command Interpreter script interpreter (CMD.EXE)? And about variable extension on SO: variable extension

+4
source share

Although I accepted @jeb's answer, in the end I had to go a different way, because I needed to output the output of my command, and at the same time on the call led to distorted results. In fact, the documentation itself for call notices

Do not use channels and call redirection characters.

Instead, it reminded @Blorgbeard of the cmd /v option (and I believe it should be lowercase, not uppercase), I realized that I could just start the subprocess:

 C:\Users\Andrew>cmd /v /c "set foo=hello, world!&& echo !foo!" hello, world! 

(For some reason, /v should appear before /c .) In quotation marks, I was able to pass my output to other utilities. One tip for those using this path: if you need to use quotation marks in these quotes, I suggest avoiding them at all and trying character codes, for example. \x20 for space, \x22 for double quotes, etc.

For example, this was the final solution to my problem (warning : may lead to eye bleeding ):

 C:\Users\Andrew>cmd /v /c "set source=C:\source& set target=C:\target& set archive=C:\archive& robocopy.exe !source! !target! /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs | sed -es/^^[\t\x20]\+// | sed -e /^^$/d | sed -es/^!source:\=\\!// | sed -es/.*/xcopy\x20\/Fvikrhyz\x20\x22!source:\=\\!^&\x22\x20\x22!archive:\=\\!^&\x22/" 
+6
source share

Try the following:

 cmd.exe /v /c "set foo=hello, world & echo !foo!" 

The /v argument allows a delayed change to a variable . This allows you to access the values โ€‹โ€‹of variables at runtime rather than at parsing (default). You do this by typing !foo! instead of %foo% (with the /v option enabled).

Instead of transferring /v you can also automatically enable delayed variable expansion through the registry, which obviously affects the entire system:

 [HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor] "DelayedExpansion"= (REG_DWORD) 1=enabled 0=disabled (default) 
+2
source share

All Articles