run two commands in one windows cmd line, one command is SET command
Asked Answered
P

2

9

[purpose]

This simple command sequence runs expected in the Windows' CMD shell:

dir & echo hello

will list the files and directories and echo the string.

However, the following command sequence does not run as expected (at least by me):

C:\Users\Administrator>set name=value & echo %name%
%name%

C:\Users\Administrator>echo %name%
value

C:\Users\Administrator>

As we can see, the first echo cannot get the environment. Could you help to comment? Any comment will be appreciated!

PS: OS:Windows 7 X64 Home Pre

Pinniped answered 27/3, 2012 at 11:35 Comment(4)
your simple experiment proves that Windows cmd-line-evaluation (as with most shell programs) can't propagate an assignment made to variables on the same line of processing. Be happy that you discovered this *feature*/limitation with only a small amount of time. Unless your cmd environment contains something like the Unix shell eval, you'll have to have the two cmds on seperate lines, i.e. set name=value new-line echo %name%. Good luck.Pentheam
@Pentheam - not quite corrrect. It is true that %name% will not give the current value when on same line as set, but delayed expansion will.Impropriety
@Impropriety : Thanks for the info, there's a lot I don't know about Windows cmd anymore. That's why I left this as a comment, you're answer however looks quite comprehensive. Thanks for sharing. +1!Pentheam
@shelter - Perhaps you should delete your incorrect comments now?Aquarelle
I
12

Your result is due to the fact that %name% is expanded during the parsing phase, and the entire line is parsed at once, prior to the value being set.

You can get the current value on the same line as the set command in one of two ways.

1) use CALL to cause ECHO %NAME% to be parsed a 2nd time:

set name=value&call echo %^name%

I put a ^ between the percents just in case name was already defined before the line is executed. Without the caret, you would get the old value.

Note: your original line had a space before the &, this space would be included in the value of the variable. You can prevent the extra space by using quotes: set "name=value" &...

2) use delayed expansion to get the value at execution time instead of at parse time. Most environments do not have delayed expansion enabled by default. You can enable delayed expansion on the command line by using the appropriate CMD.EXE option.

cmd /v:on
set "name=value" & echo !name!

Delayed expansion certainly can be used on the command line, but it is more frequently used within a batch file. SETLOCAL is used to enable delayed expansion within a batch file (it does not work from the command line)

setlocal enableDelayedExpansion
set "name=value" & echo !name!
Impropriety answered 28/3, 2012 at 2:24 Comment(7)
Thank you very much for your knowledgeable comments! The first one looks excellent and concise! I will thus choose the first one! :)Pinniped
NOTE: If the first solution above is used in a batch file, escape the %'s with second ones like set name=value&call echo %%name%%Aquarelle
EDIT - Added ^ to the CALL solution, just in case name was already defined with an old value.Impropriety
here example with little counter: set /a "count=count+1" & call echo Date: %date% Time: %time% __Run: %^count%Reube
there is an issue in for cycle, I can't force to print new time, I get in all lines same time for /L %i in (1,1,100) do (set myString=%time:~0,2%_%time:~3,2%_%time:~6,5%& call echo %^myString% & timeout 2)Vassaux
@Vassaux - You obviously missed the central point to the entire question and answer. Reread the first sentence in my answer, and then apply either of my solutions to the SET command.Impropriety
thanks, I got it, I have added ^ before %^time% and now I have every line in cycle new time for /L %i in (1,1,10) do (call set name=%^time%&call echo %^name% & timeout 2) 17:45:33.17 17:45:35.12 17:45:37.17Vassaux
F
4

You can also use cmd /V /C (with /V to enable delayed expansion).
That is great to set an environment variable for just one command in Windows cmd.exe:

cmd /V /C "set "name=value" && echo !name!"
value

Note the usage of double-quotes in set "name=value" to avoid the extra space after value.
For instance, without double-quotes:

cmd /V /C "set name=value && echo '!name!'"
'value '

You would need to think to remove the space between value and &&:

cmd /V /C "set name=value&& echo '!name!'"
'value'

But using double-quotes makes the assignment more explicit.

Floe answered 5/8, 2015 at 6:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.