The following batch script prints out my current working directory.
echo %cd%
But I didn't define the cd variable. So who does this? Is there anything else like this?
I also checked the Environment Variables, there's none with the name of cd. So is this built into the cmd.exe?
Thanks.
see HELP SET ...
If Command Extensions are enabled,
then there are several dynamic
environment variables that can be
expanded but which don't show up in
the list of variables displayed by
SET. These variable values are
computed dynamically each time the
value of the variable is expanded. If
the user explicitly defines a variable
with one of these names, then that
definition will override the dynamic
one described below:
%CD% - expands to the current
directory string.
%DATE% - expands to current date using
same format as DATE command.
%TIME% - expands to current time using
same format as TIME command.
%RANDOM% - expands to a random decimal
number between 0 and 32767.
%ERRORLEVEL% - expands to the current
ERRORLEVEL value
%CMDEXTVERSION% - expands to the
current Command Processor Extensions
version number.
%CMDCMDLINE% - expands to the original
command line that invoked the
Command Processor.
Run SET /? and in the end you'll find the answer and some other vars like that as well.
The value is stored by the command shell, I believe.
It's a built-in behavior of the batch processor, and has the same basic behavior as ERRORLEVEL.
Related
I'm trying to create desktop shortcuts to a private page we work with that will open in Edge, direct to a specific URL, and pass the GUID as a URL parameter.
I've tried the following but as you can expect, only the string "powershell" is passed on to the URL, not the returned GUID.
SET a=powershell -Command "[guid]::NewGuid().ToString()"
C:\Windows\System32\cmd.exe /c start msedge "https://www.website.com/page?user="%a% --no-first-run
How can I replace the %a% portion of the URL with the returned contents of the system GUID?
powershell -Command "[guid]::NewGuid().ToString()"
Note:
This answer addresses the question as asked: it captures the output from a PowerShell command in a batch-file variable for later use in the same batch file.
Alternatively, the specific task at hand can also be performed in full by a single PowerShell command, as shown in zett42's helpful answer.
Batch files (executed by cmd.exe) have no concept of a what is known as command substitution in POSIX-compatible shells (a feature that PowerShell itself provides too, though it has no official name there): the ability to assign a command's output to a variable.[1]
Instead, you must use a for /f loop to capture command output in a variable (which generally loops over each output line, but in your case there is only one output line):
#echo off
setlocal
:: Capture the output from a PowerShell command in variable %guid%, via
:: a for /f loop:
for /f "usebackq delims=" %%a in (`powershell -Command "[guid]::NewGuid().ToString()"`) do set "guid=%%a"
:: Note: No need for `cmd /c` from a batch file to use `start`
start "" msedge "https://www.website.com/page?user=%guid%" --no-first-run
Note: setlocal, while not strictly necessary, localizes any variable definitions to the batch file at hand.
Run for /? in a cmd.exe session for help.
This answer discusses using for /f to capture command output in more detail; notably:
usebackq isn't strictly necessary here, but is generally advisable to give you the freedom to use both ' and " quoting in the command line being invoked.
Similarly, delims= isn't strictly necessary here, since the output by definition contains no spaces, but it is generally advisable if the intent is to capture an output line in full.
The "" as the first start argument isn't strictly necessary here, but in general it is useful when invoking applications whose paths must be double-quoted. Without "" as the first argument, a double-quoted application path would be interpreted as starts window-title argument (which only meaningfully applies to console applications).
[1] In POSIX-compatible shells, use $(...) (e.g, captured="$(whoami)"). In PowerShell, you can use the command -as-is as the RHS of the assignment (e.g., $captured = whoami)
It is possible to do all of this directly using a PowerShell one-liner:
powershell -noprofile -command start msedge \"https://www.website.com/page?user=$(New-Guid) --no-first-run\"
Passing -noprofile to powershell.exe is most of the time a good idea to reduce startup time and provide a more predictable environment as no user profile will be loaded.
start is an alias for the Start-Process command.
Here start gets passed two positional arguments, the name of the process to start (-FilePath parameter) and the process's arguments as a single string (-ArgumentList parameter). Therefore, the 2nd argument must be quoted. To pass the quotes from the command processor cmd.exe through to PowerShell, they must be backslash-escaped.
Within the process's parameter string, the subexpression operator $(…) is used to call the New-Guid command inline and convert it to a string (by implicitly calling the .ToString() method of the Guid object it returns).
If you actually need to use the GUID as a variable in other parts of your batch script (which is not clear from the question), then this helpful answer provides a solution.
This question expands on the comments on this deleted answer. I claimed that an unexpanded variable reference in the PATH would not be expanded when searching for an executable, but Ken said he didn't see the same behaviour that I did.
Note that the ordinary situation is subtly but critically different: subject to certain conditions, environment variables are automatically expanded when the PATH environment variable is built from the information in the registry. I'm talking about the case where, for one reason or another, this hasn't happened, so the actual environment block of the cmd.exe process contains a PATH which still has environment variable references in it.
Here is the code I built to test this behaviour:
md test1
echo echo hello! > test1\test1.cmd
set TESTPATH=%cd%\test1
set percent=%%
set PATH=c:\windows\system32;c:\windows;c:\windows\system32\Wbem;%percent%TESTPATH%percent%
set PATH
set TESTPATH
test1
cmd /c test1
start test1.cmd
and this is the result on my machine:
C:\working\testpath>test
C:\working\testpath>md test1
C:\working\testpath>echo echo hello! 1>test1\test1.cmd
C:\working\testpath>set TESTPATH=C:\working\testpath\test1
C:\working\testpath>set percent=%
C:\working\testpath>set PATH=c:\windows\system32;c:\windows;c:\windows\system32\
Wbem;%TESTPATH%
C:\working\testpath>set PATH
Path=c:\windows\system32;c:\windows;c:\windows\system32\Wbem;%TESTPATH%
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.py;.pyw
C:\working\testpath>set TESTPATH
TESTPATH=C:\working\testpath\test1
C:\working\testpath>test1
'test1' is not recognized as an internal or external command,
operable program or batch file.
C:\working\testpath>cmd /c test1
'test1' is not recognized as an internal or external command,
operable program or batch file.
C:\working\testpath>start test1.cmd
The system cannot find the file test1.cmd.
What is the expected behaviour? Does it vary depending on the version of Windows and/or other factors?
There are two entirely different points of view in this question:
Q: How to expand the values of variables embedded in another one? This point is not specific to PATH variable, but works on anyone.
A: Enclose the names of the variables in exclamation marks and enable delayed expansion when you want to expand such values:
#echo off
setlocal EnableDelayedExpansion
set TESTPATH=%cd%\test1
set "PATH=c:\windows\system32;c:\windows;c:\windows\system32\Wbem;^!TESTPATH^!"
set PATH
echo PATH=%PATH%
Q: Does cmd.exe such delayed expansion when it use PATH to locate an executable file?
A: No. cmd.exe uses the values in PATH variable as they appear, with no further processing. Any special character that may appear in PATH, like percents or exclamation-marks, are taking literally.
This is Windows 7 command prompt question.
Suppose I have environment variable which were set in a next way:
set FILE_SRC="D:\Users\me\Documents and Settings"
I would like to call form command line utility which will get one of directory files as argument:
fooUtil.exe %FILE_SRC%\fileName.txt
In this case shell fails to construct correct path string. Instead of it utility get next argument:
"D:\Users\me\Documents and Settings"\fileName.txt
What is a correct way? Again, I talk about prompt command line and not a batch file.
I make it so ...
set "FILE_SRC=D:\Users\me\Documents and Settings"
fooUtil.exe "%FILE_SRC%\fileName.txt"
This works also with special characters.
set "line=lines & edges = figures"
#echo "%line%"
Just skip the quote marks when setting the variable. The variable will be set to the value terminated by a newline, not space.
I have created and alias named pwd for echo %cd% (#DOSKEY pwd=echo %cd%). I have saved it in bat file and configured it to autorun with command processor.
Now whenever I run the command pwd in my command processor it returns with the C:\windows\system32 no matter in which path I am currently in. whereas when I run the echo %cd% it returns the right path I am in.
How do I solve this problem? Is it because of the parameter I am passing to echo? This parameter should update according to the path I am going in. It seems it updates just once when the command prompt is loaded with aliases.
That is because %cd% is expanded during the definition of the macro, not when it is executed.
From a batch file, you should use:
#DOSKEY pwd=echo %%cd%%
If defining from the command line, the expansion rules are different, so you would need something like:
DOSKEY pwd=echo %^cd%
But there is an even simpler method that works in all cases. The CD command without arguments simply lists the current directory. Just enclose the command in parentheses to prevent arguments from being passed.
#DOSKEY pwd=(cd)
I'm trying to use Jenkins (Global) environment variables in my xcopy script.
${WORKSPACE} doesn't work
"${WORKSPACE}" doesn't work
'${WORKSPACE}' doesn't work
I know nothing about Jenkins, but it looks like you are trying to access environment variables using some form of unix syntax - that won't work.
If the name of the variable is WORKSPACE, then the value is expanded in Windows batch using
%WORKSPACE%. That form of expansion is performed at parse time. For example, this will print to screen the value of WORKSPACE
echo %WORKSPACE%
If you need the value at execution time, then you need to use delayed expansion !WORKSPACE!. Delayed expansion is not normally enabled by default. Use SETLOCAL EnableDelayedExpansion to enable it. Delayed expansion is often needed because blocks of code within parentheses and/or multiple commands concatenated by &, &&, or || are parsed all at once, so a value assigned within the block cannot be read later within the same block unless you use delayed expansion.
setlocal enableDelayedExpansion
set WORKSPACE=BEFORE
(
set WORKSPACE=AFTER
echo Normal Expansion = %WORKSPACE%
echo Delayed Expansion = !WORKSPACE!
)
The output of the above is
Normal Expansion = BEFORE
Delayed Expansion = AFTER
Use HELP SET or SET /? from the command line to get more information about Windows environment variables and the various expansion options. For example, it explains how to do search/replace and substring operations.
In windows you should use %WORKSPACE%.
I should this On Windows, environment variable expansion is %BUILD_NUMBER%