Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How set a variable and then use it in the same line in command prompt

Tags:

batch-file

cmd

I want to set a variable e.g. %p% and then use it in the same line in CMD.

e.g.:

set p=notepad.exe&%p%

This not works. But %p% is set for the next line. Therefore if I execute this line for second time, it works.

How can I use %p% in the same line?

like image 207
A.Danesh Avatar asked Oct 08 '14 07:10

A.Danesh


People also ask

How do I assign a variable to the command line?

To set (or change) a environment variable, use command " set varname=value ". There shall be no spaces before and after the '=' sign. To unset an environment variable, use " set varname= ", i.e., set it to an empty string.

How do I pass a variable in command prompt?

To pass variable values via the command line, use the PrjVar ( pv ) or PSVar ( psv ) arguments for the project and project suite variables respectively. Variable values you pass via the command line are temporary.

What is %% A in command line?

Use double percent signs ( %% ) to carry out the for command within a batch file. Variables are case sensitive, and they must be represented with an alphabetical value such as %a, %b, or %c. ( <set> ) Required. Specifies one or more files, directories, or text strings, or a range of values on which to run the command.


1 Answers

When you execute a batch file, each line or block of lines (lines enclosed in parenthesis) is first parsed and then executed. During the parse, the read operations on the variables are replaced with the value inside the variable before the commands are executed. So if in a line/block a variable value is changed, you can not retrieve this changed value as the parser has removed the read operation with the value in the variable before the change has been made.

So, your code

set p=notepad.exe&%p%

is parsed and converted to

set p=notepad.exe&

where the read operation to get %p% has been replaced with the value in the variable (the sample assumes the variable is empty). Then this parsed line is executed.

Why does it work the second time? Because in the previous run the variable has been set and, if it has not been reset, when the parser do the replacement in the second run the variable contains a value to replace in the line.

To see that this is a parse before execute behaviour, you can change your line to

set p=notepad.exe&set p

that is, set the variable and dump the environment content (variables starting with p) and you will see that the variable has been set to notepad.exe. As this line does not contain any read operation on the variable everything works as expected.

How to solve your problem? There are some options

Delayed expansion

When delayed expansion is enabled, the syntax on variable reads can be changed, where needed, from %var% to !var!, indicating to the parser that the substitution on the read operation needs to be delayed until the command execution

setlocal enabledelayedexpansion
set p=notepad.exe&!p!

This same behaviour can be enabled if the command processor is called with /v:on

cmd /v:on /c "set p=notepad.exe&!p!"

Force a second parse on the command

This uses the call command to force a second parse on the line

set p=notepad.exe&call %%p%%

The first default parse replaces the literal %%p%% with the literal %p% (%% is a escaped percent sign) without doing any variable replacement, and when the call command is executed, the line is parsed again, so the literal %p% is interpreted as a variable read and is replaced with the value in the variable

What to use? It depends. Delayed expansion solution has better execution times that call solution (call command does a lot more work), but when delayed expansion is enabled exclamation characters (!) contained in the data become a problem that needs to be properly handled.

like image 87
MC ND Avatar answered Sep 16 '22 22:09

MC ND