MS-DOS and Windows command line setlocal command
The setlocal command enables local environments to be changed without affecting anything else.
Availability
Setlocal is an internal command that is available in the following Microsoft operating systems.
Setlocal syntax
Begins localization of environment changes in a batch file. Environment changes made after SETLOCAL is issued are local to the batch file. ENDLOCAL must be issued to restore the previous settings. When the end of a batch script is reached, an implied ENDLOCAL is executed for any outstanding SETLOCAL commands issued by that batch script.
If Command Extensions are enabled, SETLOCAL changes as follows:
SETLOCAL batch command now accepts optional arguments:
| ENABLEEXTENSIONS / DISABLEEXTENSIONS |
Enable or disable command processor extensions. See CMD for details. |
| ENABLEDELAYEDEXPANSION / DISABLEDELAYEDEXPANSION |
Enable or disable delayed environment variable expansion. See SET /? for details. |
These modifications last until the matching ENDLOCAL command, regardless of their settings before the SETLOCAL command.
The SETLOCAL command sets the ERRORLEVEL value if given an argument. It will be zero if one of the two valid arguments is given and one otherwise. You can use this in batch scripts to determine if the extensions are available, using the following technique:
The example above works because on old versions of CMD.EXE, SETLOCAL does NOT set the ERRORLEVEL value. The VERIFY command with a bad argument initializes the ERRORLEVEL value to a non-zero value.
Setlocal examples
Ran in a batch file, the setlocal command would have all environment changes only affected in the batch file.
Also see Microsoft's above example shown in the syntax for other ways this command can be used.
Setlocal enableextensions что это
Begin localisation of environment variables in a batch file.
Changes made to an Environment Variable after SETLOCAL has been issued are local to the batch file. ENDLOCAL must be issued to restore the previous settings.
Overloading a variable
SETLOCAL can be used more than once in the same batch file so that multiple values can be stored in one Environment Variable.
For example:
@echo off
::
::Standard commission
SET V_Commission=20
echo %V_Commission%
::
::Super commission
SETLOCAL
set V_Commission=30
echo %V_Commission%
::
::Premium commission
SETLOCAL
set V_Commission=40
echo %V_Commission%
ENDLOCAL
::
::Back to Super commission
echo %V_Commission%
ENDLOCAL
::
::back to Standard commission
echo %V_Commission%
DISABLEEXTENSIONS- will attempt to disable Command extensions. (ENABLEEXTENSIONS — will attempt to re-enable)
SETLOCAL will set an ERRORLEVEL if given an argument. It will be zero if one of the two valid arguments
is given and one otherwise.
You can use this in a batch file to determine if command extensions are available, using the following technique:
This works because "VERIFY errors" sets ERRORLEVEL to 1 and then the SETLOCAL will fail to reset the ERRORLEVEL value if extensions are not available (e.g. if the script is running under command.com)
If Command Extensions are permanently disabled then SETLOCAL ENABLEEXTENSIONS will not restore them.
Windows Batch Scripting: Variables
Today we’ll cover variables, which are going to be necessary in any non-trivial batch programs. The syntax for variables can be a bit odd, so it will help to be able to understand a variable and how it’s being used.
Variable Declaration
DOS does not require declaration of variables. The value of undeclared/uninitialized variables is an empty string, or «» . Most people like this, as it reduces the amount of code to write. Personally, I’d like the option to require a variable is declared before it’s used, as this catches silly bugs like typos in variable names.
Variable Assignment
The SET command assigns a value to a variable.
NOTE: Do not use whitespace between the name and value; SET foo = bar will not work but SET foo=bar will work.
The /A switch supports arthimetic operations during assigments. This is a useful tool if you need to validated that user input is a numerical value.
A common convention is to use lowercase names for your script’s variables. System-wide variables, known as environmental variables, use uppercase names. These environmental describe where to find certain things in your system, such as %TEMP% which is path for temporary files. DOS is case insensitive, so this convention isn’t enforced but it’s a good idea to make your script’s easier to read and troubleshoot.
WARNING: SET will always overwrite (clobber) any existing variables. It’s a good idea to verify you aren’t overwriting a system-wide variable when writing a script. A quick ECHO %foo% will confirm that the variable foo isn’t an existing variable. For example, it might be tempting to name a variable “temp”, but, that would change the meaning of the widely used “%TEMP%” environmental varible. DOS includes some “dynamic” environmental variables that behave more like commands. These dynamic varibles include %DATE% , %RANDOM% , and %CD% . It would be a bad idea to overwrite these dynamic variables.
Reading the Value of a Variable
In most situations you can read the value of a variable by prefixing and postfixing the variable name with the % operator. The example below prints the current value of the variable foo to the console output.
There are some special situations in which variables do not use this % syntax. We’ll discuss these special cases later in this series.
Listing Existing Variables
The SET command with no arguments will list all variables for the current command prompt session. Most of these varaiables will be system-wide environmental variables, like %PATH% or %TEMP% .

NOTE: Calling SET will list all regular (static) variables for the current session. This listing excludes the dynamic environmental variables like %DATE% or %CD% . You can list these dynamic variables by viewing the end of the help text for SET, invoked by calling SET /?
Variable Scope (Global vs Local)
By default, variables are global to your entire command prompt session. Call the SETLOCAL command to make variables local to the scope of your script. After calling SETLOCAL , any variable assignments revert upon calling ENDLOCAL , calling EXIT , or when execution reaches the end of file (EOF) in your script.
This example demonstrates changing an existing variable named foo within a script named HelloWorld.cmd . The shell restores the original value of %foo% when HelloWorld.cmd exits. 
A real life example might be a script that modifies the system-wide %PATH% environmental variable, which is the list of directories to search for a command when executing a command. 
Special Variables
There are a few special situations where variables work a bit differently. The arguments passed on the command line to your script are also variables, but, don’t use the %var% syntax. Rather, you read each argument using a single % with a digit 0-9, representing the ordinal position of the argument. You’ll see this same style used later with a hack to create functions/subroutines in batch scripts.
There is also a variable syntax using ! , like !var! . This is a special type of situation called delayed expansion. You’ll learn more about delayed expansion in when we discuss conditionals (if/then) and looping.
Command Line Arguments to Your Script
You can read the command line arguments passed to your script using a special syntax. The syntax is a single % character followed by the ordinal position of the argument from 0 – 9 . The zero ordinal argument is the name of the batch file itself. So the variable %0 in our script HelloWorld.cmd will be “HelloWorld.cmd”.
The command line argument variables are * %0 : the name of the script/program as called on the command line; always a non-empty value * %1 : the first command line argument; empty if no arguments were provided * %2 : the second command line argument; empty if a second argument wasn’t provided * …: * %9 : the ninth command line argument
NOTE: DOS does support more than 9 command line arguments, however, you cannot directly read the 10th argument of higher. This is because the special variable syntax doesn’t recognize %10 or higher. In fact, the shell reads %10 as postfix the %0 command line argument with the string “0”. Use the SHIFT command to pop the first argument from the list of arguments, which “shifts” all arguments one place to the left. For example, the the second argument shifts from position %2 to %1 , which then exposes the 10th argument as %9 . You will learn how to process a large number of arguments in a loop later in this series.
Tricks with Command Line Arguments
Command Line Arguments also support some really useful optional syntax to run quasi-macros on command line arguments that are file paths. These macros are called variable substitution support and can resolve the path, timestamp, or size of file that is a command line argument. The documentation for this super useful feature is a bit hard to find – run ‘FOR /?’ and page to the end of the output.
fI is the full path to the folder of the first command line argument
fsI is the same as above but the extra s option yields the DOS 8.3 short name path to the first command line argument (e.g., C:\PROGRA
1 is usually the 8.3 short name variant of C:\Program Files ). This can be helpful when using third party scripts or programs that don’t handle spaces in file paths.
dpI is the full path to the parent folder of the first command line argument. I use this trick in nearly every batch file I write to determine where the script file itself lives. The syntax SET parent=%
dp0 will put the path of the folder for the script file in the variable %parent% .
nxI is just the file name and file extension of the first command line argument. I also use this trick frequently to determine the name of the script at runtime. If I need to print messages to the user, I like to prefix the message with the script’s name, like ECHO %
n0: some message instead of ECHO some message . The prefixing helps the end user by knowing the output is from the script and not another program being called by the script. It may sound silly until you spend hours trying to track down an obtuse error message generated by a script. This is a nice piece of polish I picked up from the Unix/Linux world.
Some Final Polish
I always include these commands at the top of my batch scripts:
The SETLOCAL command ensures that I don’t clobber any existing variables after my script exits. The ENABLEEXTENSIONS argument turns on a very helpful feature called command processor extensions. Trust me, you want command processor extensions. I also store the name of the script (without the file extension) in a variable named %me% ; I use this variable as the prefix to any printed messages (e.g. ECHO %me%: some message ). I also store the parent path to the script in a variable named %parent% . I use this variable to make fully qualified filepaths to any other files in the same directory as our script.
Posted by Steve Jansen Mar 1 st , 2013 batch, scripting, shell, windows
Comments
Hi, I’m Steve. I’m a software developer loving life in Charlotte, NC, an (ISC) 2 CSSLP and an avid fan of Crossfit.
And, no, I’m not Steve Jansen the British jazz drummer, though that does sound like a sweet career.
Setlocal enableextensions что это
I notice in most scripts, the two are usually in the same line as so:
Are the two in fact separate commands and can be written on separate lines?
Will setting ENABLEDELAYEDEXPANSION have an adverse effect on a script if it is set on the first lines of the script and not disabled until the end of the script?
![]()
4 Answers 4
I think you should understand what delayed expansion is. The existing answers don’t explain it (sufficiently) IMHO.
Typing SET /? explains the thing reasonably well:
Delayed environment variable expansion is useful for getting around the limitations of the current expansion which happens when a line of text is read, not when it is executed. The following example demonstrates the problem with immediate variable expansion:
would never display the message, since the %VAR% in BOTH IF statements is substituted when the first IF statement is read, since it logically includes the body of the IF, which is a compound statement. So the IF inside the compound statement is really comparing «before» with «after» which will never be equal. Similarly, the following example will not work as expected:
in that it will NOT build up a list of files in the current directory, but instead will just set the LIST variable to the last file found. Again, this is because the %LIST% is expanded just once when the FOR statement is read, and at that time the LIST variable is empty. So the actual FOR loop we are executing is:
which just keeps setting LIST to the last file found.
Delayed environment variable expansion allows you to use a different character (the exclamation mark) to expand environment variables at execution time. If delayed variable expansion is enabled, the above examples could be written as follows to work as intended:
Another example is this batch file:
This prints x2 and y2 : every 1 gets replaced by a 2.
Without setlocal enabledelayedexpansion , exclamation marks are just that, so it will echo !b:1=2! twice.
Because normal environment variables are expanded when a (block) statement is read, expanding %b:1=2% uses the value b has before the loop: z2 (but y2 when not set).