Windows shell script variables

  • Overview
  • Part 1 – Getting Started
  • Part 2 – Variables
  • Part 3 – Return Codes
  • Part 4 – stdin, stdout, stderr
  • Part 5 – If/Then Conditionals
  • Part 6 – Loops
  • Part 7 – Functions
  • Part 8 – Parsing Input
  • Part 9 – Logging
  • Part 10 – Advanced Tricks

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.

SET foo=bar

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.

SET /A four=2+2
4

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.

C:\> SET foo=bar
C:\> ECHO %foo%
bar

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%.

Screenshot of the SET command

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.

Demonstration of the SETLOCAL command

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.

Demonstration of the SETLOCAL 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 09. 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.

  • %~I removes quotes from the first command line argument, which is super useful when working with arguments to file paths. You will need to quote any file paths, but, quoting a file path twice will cause a file not found error.

SET myvar=%~I

  • %~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:

SETLOCAL ENABLEEXTENSIONS
SET me=%~n0
SET parent=%~dp0

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.


<< Part 1 – Getting Started


Part 3 – Return Codes >>

Environment variables are a collection of dynamic named values that are saved on the system and utilized by programs that are running in shells or subshells on Linux and Unix-based systems. An environment variable is, to put it simply, a variable with a name and a corresponding value.

You can alter the system’s operation and the actions of its programs by using environment variables. For instance, the environment variable may keep track of the default text editor or browser, the location of executable files, or the keyboard layout and system locale.

Environment Variables and Shell Variables 

Variables are formatted as follows:

KEY=value
KEY="Some other value"
KEY=value1:value2
  • When naming the variables, the case matters. By convention, environment variables’ names must be in UPPER CASE.
  • When assigning values to the variable, the colon: the character must be used to separate the values.
  • There is no white space around the equals = sign.

The two fundamental groups into which variables can be separated are the environment and the shell.

All child processes and shells that are launched inherit any environment variables that are system-wide and available.

Only the current shell instance is affected by shell variables. There are specific internal shell variables for each shell, including zsh and bash.

In Linux, a number of commands are available to list and set environment variables, including the following:

  • Using the command env, you can execute a different program in a unique environment without changing the one that is already in use. If it is used without an argument, a list of the current environment variables will be printed.
  • The command printenv prints every environment variable or just the ones that are supplied.
  • Using the set command, shell variables can be set or unset. Without an argument, it will display a list of all variables, including shell and environment variables as well as shell functions.
  • Delete shell and environment variables with the unset command.
  • Environment variables are set with the command export.

Printing Environment Variables 

In order to display environment variables printenv is the most used command that serves the purpose. Only that variable’s value is displayed, if its name is supplied as an argument to the command. printenv prints a list of all environment variables, one variable per line, if no argument is given.

For instance, you would execute: to display the value of the HOME environment variable.

 

For instance, you would execute: to display the value of the PATH environment variable.

 

For instance, running the printenv or env command without any arguments will display a list of all environment variables:

 

Some of the most prevalent environmental variables are listed below:

  • USER — The user who is currently logged in.
  • HOME — The current user’s home directory.
  • EDITOR — The file editor that will be used by default. When you type edit in your terminal, this is the editor that will be used.
  • SHELL — The current user’s shell path, such as bash or zsh.
  • LOGNAME — The current user’s name.
  • PATH — A list of folders that will be searched when commands are executed. When you run a command, the system will scan those directories in the order listed above and utilize the first executable found.
  • LANG — The current locale configuration.
  • TERM — Terminal emulation at the moment.
  • MAIL — The location of the current user’s email.

Only the environment variables are printed using the printenv and env commands. 

Other Methods to List Linux Environment Variables

The following command will display shell and environment variables using the built-in shell utility declare:-

declare

 

 

Using the set command, you may retrieve a list of every variable, including environment, shell variables, and shell functions:

set

 

 

You should most likely pipe the output to the less command because the command will output a lengthy list of all variables.

 

 

Persistent Environment Variables

Environment variables must be defined in the bash configuration files if you want them to be persistent. In most Linux systems, when a new session is launched, environment variables are read from the following files:

  •  The system-wide environment variables are made to be set using the /etc/environment file. Following is the format for the same: 
$ FOO=bar
$ VAR _A="GeeksforGeeks"
  • The variables set in this file are loaded in the /etc/profile each time a bash login shell is used. Declare environment variables in this file using the export command:
$ export JAVA_HOME="/path/to/java/home"
$ export PATH=$PATH:$JAVA_HOME/bin
  • Shell configuration files specific to each user. For instance, if you’re using Bash, you can define the variables in the /.bashrc file:
$ export PATH="$HOME/bin:$PATH"

You can add additional environment variables to the running shell session by using the source command:

$ source ~/.bashrc

Setting Shell and Environment Variables 

Using the name VAR_A and the value Welcome, you can easily create a new shell variable by typing:

Creating Shell Variables

Let’s start by setting up a shell variable for the active session. To accomplish this, all we need to do is provide a name and a value. We’ll stick to tradition and set the variable to a simple string while maintaining the variable name in all caps.

Now there is a shell variable. Despite being present in our current session, this variable won’t be shared with any child processes.

In the set output, we can observe this by grepping for our new variable:

 

By performing the identical thing with printenv, we can confirm that this is not an environmental variable:

 

There should be no output produced.

Creating Environmental Variables

Let’s now convert the shell variable to an environmental variable. Exporting the variable will allow us to achieve this. The appropriate command to do so is named as follows:

 

As a result, our variable will now be an environment variable. This can be verified by rechecking our environmental listing with printenv command.

Demoting and Unsetting Variables

We continue to declare our VAR_A variable as an environmental variable. By typing the following, we can turn it back into a shell variable:

 

However, it is still a shell variable:

 

The unset command can be used to totally unset a variable, whether it be shell or environmental:

 

The variable was unset, thus nothing is returned.

Batch Script of Environment Variables

Following is the batch script of environment variables: PATH, HOME, LANG, and SHELL.

Script:

#!/bin/bash
echo $PATH
echo $HOME
echo $LANG
echo $SHELL

Output:

 

Batch manual. Keywords: batch bat shell script scripting windows

LEARN HOW TO BATCH

Table of contents

  • What you have to know before we start
    • Change your mindset & be patient — Easy is gonna become hard
    • The .bat extension
    • There are only 2 types: String and Number
    • Avoid spaces
    • Use setlocal enabledelayedexpansion
    • Script returned value — 0 vs 1
    • Avoid blocks as much as possible
    • You should organise your script using subroutines
  • Getting started
    • Basic script example
    • Subroutines
      • Basic
      • Intermediate
      • Advanced — Returning multiple values
    • String manipulation
  • How to
    • How to set a variable from a command output?
    • How to get the parent folder of the current file?
  • Annex
    • Special variables

What you have to know before we start

Change your mindset & be patient — Easy is gonna become hard

You’re dealing with some super primitive shit here. The cmd.exe compiler is extremely primitive and what is trivial to do in other language is now gone. This is why I’m writing this document. My mission is to help you swear less at your machine than what I did when I had to learn this horrible piece of shit crap from Microsoft.

The .bat extension

To run a batch script, simply enter the name of your .bat file in the terminal:

> hello.bat

This executes the scripts defined in the hello.bat file.

There are only 2 types: String and Number

Forget about booleans, objects, … The following does not set the var_01 to a truthy boolean. Instead, it sets the string value true.

set var_01=true

Avoid spaces

Batch scripts have a really fucked up unpredictable way of dealing with spaces, so do your best to not use them:

:: Don't do this
set hello = World

:: Instead, use this
set hello=World

Use setlocal enabledelayedexpansion

I MEAN IT, JUST FREAKING USE THIS. Trust me, use this, otherwise, your code will start generating really randomly.

TL;DR

If your script mutates variable, and if those variables are used in IFs, then if you don’t use this set up, the variables will not be set sequentially based on your code execution. You’ll be scratching your heads for hours wondering why your code is not working and you’ll see weird stuff when you echo your variables.

Before delayed expansion

@echo off
set hello=world
echo %hello%

After delayed expansion

@echo off
setlocal enabledelayedexpansion

set hello=world
echo !hello!

endlocal

Explanation

Delayed Expansion will cause variables within a batch file to be expanded at execution time rather than at parse time, this option is turned on with the SETLOCAL EnableDelayedExpansion command.

Variable expansion means replacing a variable (e.g. %windir%) with its value C:\WINDOWS.

Script returned value — 0 vs 1

A successful script returns 0 while an unsuccessful one returns 1. This value is stored inside the global ERRORLEVEL variable, so you can check it after the script execution to determine whether the script was successful or not.

Avoid blocks as much as possible

The cmd.exe compiler likes reading commands that start and end on the same line. If you think that your code inside an if block is only executed if the condition is true, then be ready for a big surprise. The following will most probably (most probably because is not that predictable, it may actually work) make your code exit:

set do_not_do_this=true
if do_not_do_this == false (
	echo Mate, do not do this!
	exit /b 1
)

echo Great mate! You did the right thing

This because the compiler will reads each line inside the block. The following 2 options are more predictable:

set do_not_do_this=true
if do_not_do_this == false echo Mate, do not do this!
if do_not_do_this == false exit /b 1

echo Great mate! You did the right thing

or

set do_not_do_this=true
if do_not_do_this == false (goto :ok) else (goto :notok)

:ok
echo Great mate! You did the right thing
goto :EOF

:notok
echo Mate, do not do this!
exit /b 1

You should organise your script using subroutines

Batch is so primitive that you will eventually need to use subroutines, so better learn how to structure your script from the beginning of your learning journey. To see how to get started with subroutines, please refer to the Subrountines section.

Getting started

Basic script example

:: This is a comment.

:: This is how you prevent the terminal to print the entire set of commands below.
@echo off
setlocal enabledelayedexpansion

:: This is how you get an array of all the arguments.
echo %*

:: This is how you access any arguments passed to the script. 
:: A new argument occurs each time there is a new space.
echo %1
echo %2

:: Prints the name of the .bat file
echo %0

:: This is how to define a variable
:: WARNING: Though it looks like we're setting a boolean, that's not the case. Remember, the only 2
:: supported types in batch are numbers and string. The line below assigns the string 'false' to the 
:: variable hello.
set hello=false 

:: This is how you store arithmetic values. If you don't use the /a flag, the 
:: arithmetic ops is interpreted as a string. 
set /a numerator=1+2

:: Reference a expandded variable
echo !hello!
:: Reference a non-expanded variable
echo %hello%

:: This is how to do an IF. Notice you need to wrap the %1 between double quotes
:: to be able to compare against an empty string to check wether it exists or not.
:: This is to cover the use case where %1 does not exist. If we don't do this and %1 
:: does not exist, an error similar to: Incorrect syntax if neq "".
:: Also, notice the "neq" operator. Something like != does not exist :(
if "%1" neq "" (
	echo Hoorayyyyy, we have a value.
) else (
	echo Oh shit, no value
)

:: This is how you do a logical AND. The "&&" or "&" do not exist in batch.
:: NOTICE: 
::	- The use the "==" logical equivalence. You could also use "equ" instead.
::	- 'exit /b 1' is how you properly exit the execution. The 1 is optional but recommended.
::	  This allows other scripts to determine whether this script was successful or not.
::	  (successful scripts return 0)
::	- The pattern <command> & exit /b 1. DO NOT use block with 2 lines (one for the 
::	  echo and one for the exit)instead, as this can have unpredictable results. 
::	  Remember, in batch, coding in one line rules.
if "%1" == "" if "%2" == "" echo ERROR: Missing required argument --name. & exit /b 1

:: This is how you do a logical OR. The "||" or "|" do not exist in batch.
set or_val=false
if "%1" neq "" set or_val=true
if "%2" neq "" set or_val=true

:: Get into the habit to write if else on a single line. The compiler seems to like this better.
if or_val equ true (echo OR is ok) else (echo OR is NOT ok)

:: This is how you do a 'for' loop.
:: NOTICE:
::	- With an the output of a command, wrap it between single quotes (e.g., list of files: dir /b /a-d).
::	- The /f option must be used to store items from an array (technically, it stands for files).
for /f %%x in ('dir /b /a-d') do echo %%x

endlocal
exit /b 0

Subroutines

Basic

Batch is so primitive that you will eventually need to use subroutines, so better learn how to structure your script from the beginning of your learning journey.

The following script outputs something similar to this:

> test.bat hello world
CORE ARGS: hello world
MAIN ARGS: world hello

test.bat:

@echo off

echo CORE ARGS: %1 %2

:: Notice how you must end with '& exit /b' to make sure the rest of the script is not executed.
call :main %2 %1 & exit /b

:main
:: Notice how you still use the %1 convention to get params
echo MAIN ARGS: %1 %2
exit /b

Intermediate

@echo off

echo CORE ARGS: %1 %2

call :main %2 %1 & exit /b

:main
setlocal enabledelayedexpansion
echo MAIN ARGS: %1 %2

:: Succeeding routine
call :divide 6 2 result
if !errorlevel! neq 0 exit /b !errorlevel!
echo 6 divided by 2 is equal to %result%

:: Failing subroutine
call :divide 6 0 result
if !errorlevel! neq 0 exit /b !errorlevel!
echo 6 divided by 1 is equal to %result%

endlocal
exit /b


:divide
setlocal enabledelayedexpansion

set /a numerator=%1
set /a denominator=%2

if "!denominator!" == "0" echo ERROR - Can't devide by 0 & exit /b 1 

set /a result=!numerator!/!denominator!

:: NOTICE:
::	- The pattern used to set the returning result: set %3=%result%
::	  Notice that we did not use set %3=!result!. I have no clue why, but you can
::	  only use %...% when setting the return value. Setting up %3 is not the best 
::	  practice though. Refer to the next section for a more advanced example.
::	- The pattern used to maintain the result value from the setlocal scope while 
::	  at the same time setting it to %3. If you had seperated the 'endlocal' and
::	  'endlocal' in 2 lines, the value stored in result would had been lost.
endlocal & set %3=%result%
exit /b

Advanced — Returning multiple values

The previous example demonstrated how to return a value by explicitly setting %3. However, this can create problem. Take for example the following sample:

call :my_routine %1 %2 result
echo %result%
exit /b

Setting %3 in :my_routine only works if it is 100% garanteed that both %1 and %2 exist, because if, for example, %2 is not set, then as far as :my_routine is concerned, result is similar to %2, not %3. In that case, when :my_routine sets %3, it does not set result.

A better solution is to return an explicit variable as follow:

call :my_routine %1 %2
echo %result%
exit /b 

:my_routine
setlocal enabledelayedexpansion
:: do stuff
set example=hello world
endlocal & set result=%example%
exit /b

It is also trivial to return many results:

call :my_routine %1 %2
echo %result_01%
echo %result_02%
exit /b 

:my_routine
setlocal enabledelayedexpansion
:: do stuff
set example_01=hello world
endlocal & set result_01=%example_01% & set result_02=What's up
exit /b

String manipulation

set sample=hello world

:: Getting a sub-string
:: this outputs hell
echo %sample:~0,4%
:: this outputs world
echo %sample:~6,200%
:: this outputs hello wor
echo %sample:~0,-2%

How to

How to set a variable from a command output?

setlocal enabledelayedexpansion

:: This exe is IIS 7.0
set appCmd="!WINDIR!\System32\inetsrv\appcmd.exe"
set website_name=demo_01

set website_status=Unknown
for /f %%x in ('!appCmd! list site !website_name! /text:state') do set website_status=%%x

echo The status of the website !website_name! is: !website_status!

endlocal

How to get the parent folder of the current file?

To refresh your mind:

:: Current working directory from where the script is invoked
echo %cd%

:: Path of this file relative to %cd%
echo %0

:: Absolute path to this file
echo %cd%\%0

Annex

Special variables

Var Description
cd Current directory where the .bat file is being called (not the directory where the file is).
WINDIR Location of the Windows folder with all its libraries and utils.
SystemDrive This is the drive letter that contains the Windows OS (e.g., C:)

In scripts, you’ll use variables to store values as you perform
various types of operations. Unlike most programming languages, you cannot
declare a variable in a command-line script without simultaneously assigning it
a value. This makes a certain amount of sense because from a practical point of
view, there’s no reason to have a variable that contains nothing. The sections
that follow discuss key concepts for working with variables, including

  • Variable names

  • Variable values

  • Variable substitution

  • Variable scope

Naming
Variables

The command shell tracks variable names in the case you use
but doesn’t care about the case when you are working with the variable. This
means variable names aren’t case-sensitive but are case-aware. Beyond this, very
few restrictions apply to variable names and you can use just about any
combination of letters, numbers, and characters to form the variable name. In
fact, all the following variable names are technically valid:

2six

85

!

?

But why in the world you’d want to use such horrendous variable
names is beyond me. With that said, how should you name your variables? Well,
the most important rule to keep in mind is that variable names should be
descriptive. Use names such as

System-name

CurrentStats

mergetotal

Net_Address

These descriptive variable names are helpful when you or someone
else needs to modify the script. And notice that there are many ways to create
multiple- word variable names. Although you are free to use whatever style you
like, most programmers format multiword variable names with a lowercase initial
letter on the first word and uppercase initial letter on each subsequent word.
Why? The reason is simple: this is a standard naming convention. Following this
convention, the variable names used previously are created as

systemName

currentStats

mergeTotal

netAddress

Note 

Keep in mind that the command shell doesn’t care about the
case. Variable names are case-aware but they’re not case-sensitive. This means
that you could refer to the systemName variable as SYSTEMNAME, systemname, or even sYStemNAMe.

Setting Variable
Values

As discussed previously, you define new variables using the
following syntax:

set variable_name=variable_value

where variable_name is the variable name and
variable_value is its related value. Spaces are valid in
both names and values. So only use spaces around the equal sign (=) if you want
the name and/or the value to include these spaces.

Unlike many programming languages, the command shell doesn’t
differentiate between various data types. All variables are stored as character
strings. This is true even when you set the variable value to a number. Thus,
the following values are stored as strings:

Current status:

311

"Error!"

12.75

using commands such as:

set varA=Current status:

set varB=311

set varC="Error!"

set varD=12.75

Don’t forget that some characters are reserved in the command
line, including @ < > & | ^. Before you use these characters, you must
escape them with the caret symbol (^) as discussed in Chapter 2, “Getting the Most from the
Command Line”—no matter where they occur in the variable value. For example, to
set these literal string values:

2 & 3 = 5

2^3

you must set the variable value as follows:

2 ^& 3 = 5

2^^3

using statements such as

set example1=2 ^& 3 = 5

set example3=2^^3

Note 

An odd thing happens if you try to echo the example values.
Instead of the equations you expect, you get either an error or an odd value.
What is happening here is that when you echo the value, the special characters
are reparsed. If you want to set a variable to a value that includes a special
character and also be able to display this value to users, you must use three
escape codes, meaning that you would use set example1=2
^^^
& 3 = 5 or set
example2=2^^^^3
. This is necessary because the value is double parsed
(once when the value is set and once when the value is
displayed).

Substituting
Variable Values

Variables wouldn’t be very useful if the only way you could
access them was with the SET command. Fortunately, you can access variable
values in other ways. One of these ways is to use variable substitution to
compare a variable name with its actual value. You saw this type of substitution
at work in the following line from a previous example in this chapter:

if "%ERRORLEVEL%"=="2" echo "An error occurred!"

Here, you are determining whether the value of the errorlevel environment variable is equal to 2 and, if it is,
you display text stating that an error occurred. The percent signs surrounding
the variable name tell the command shell you are referencing a variable. Without
these percent signs, Windows would perform a literal comparison of “ERRORLEVEL”
and “2”. Note also the use of quotation marks in the example. The quotation
marks ensure an exact comparison of string values.

Another way to use substitution is to replace a variable name with
its actual value. For example, you might want to create a script that can be run
on different computers, so rather than hard-coding the path to the system root
directory as C:\Windows, you could use the environment variable systemroot, which references the system root of the
particular computer being accessed. With this in mind, you use the following
line of code in your script:

cd %SYSTEMROOT%\System32

instead of this line of code:

cd C:\Windows\System32

You can also use variable substitution when you are assigning
variable values, such as

systemPath=%SystemRoot%\System32

Variable substitution can be quite powerful. Consider the code
snippet shown as Listing 3-3.

Listing 3-3: Sample Script Header

@echo off

@if not "%OS%"=="Windows_NT" goto :EXIT

@if "%1"=="" (set INFO=echo && set SEXIT=1) else (set INFO=rem &&

set SEXIT=0)

%INFO% ************************

%INFO% Script: SystemInfo.bat

%INFO% Creation Date: 2/2/2004

%INFO% Last Modified: 3/15/2004

%INFO% Author: William R. Stanek

%INFO% E-mail: williamstanek@aol.com

%INFO% ************************

%INFO% Description: Displays system configuration information

%INFO% Including system name, IP configuration

%INFO% and Windows version.

%INFO% ************************

%INFO% Files: Stores output in c:\current-sys.txt.

%INFO% ************************

@if "%SEXIT%"=="1" goto :EXIT

@title "Configure Scheduling..."

cls

color 07

Listing 3-3 is a
standard header that I use in some of my scripts. The first if statement checks to see what operating system is running.
If it is Windows 2000 or later, meaning Windows 2000, Windows XP, or Windows
Server 2003, the script continues execution. Otherwise a goto
subroutine is called. The second if statement checks
the value of the first argument passed in to the script. If the script is called
with no arguments, instances of %INFO% are replaced with
echo, which writes the script documentation to the output.
If the script is called with one or more arguments, instances of %INFO% are replaced with rem to
designate that the associated lines are comments.

Note 

Don’t worry if you don’t understand the example completely.
You’ll learn all about conditional execution and subroutines later in the
chapter in the sections titled, “Command-Line Selection Statements” and “Creating Subroutines and
Procedures
.”

Localizing
Variable Scope

Changes you make to variables in the command shell using set are localized, meaning that they apply only to the
current command shell instance or to command shells started within the current
command shell (nested command shells) and are not available to other system
processes. Further, once you exit the command shell in which variables were
created, the variables no longer exist.

Sometimes you may want to limit the scope of variables even
further than their current command-shell process. To do this, you can create a
local scope within a script that ensures any variable changes are localized to
that specific area within the script. Later, you can end the local scope and
restore the environment to its original settings.

You can mark the start of a local scope within a script using the
SETLOCAL command and then end the local scope with an ENDLOCAL command. Several
events take place when you use these commands. The call to SETLOCAL creates a
snapshot of the environment. Any changes you make within the scope are then
localized and discarded when you call ENDLOCAL. An example using SETLOCAL and
ENDLOCAL follows:

@echo off

set sysCount=0

set deviceCount=0

rem Start localization

setlocal

set sysCount=5

set deviceCount=5

echo Local count: %sysCount% system edits ^& %deviceCount% device

checks

endlocal

echo Count: %sysCount% system edits ^& %deviceCount% device checks

The output of the script is

Local count: 5 system edits & 5 device checks

Count: 0 system edits & 0 device checks

As you can see, local scopes behave much like nested command
shells. As with the nested command shells, you can nest several layers of
localization. And though each layer inherits the environment settings of its
parent, any changes in the nested layer are not reflected in the parent
environment.

Дисклеймер

Мне 12 и я сам в этой теме плохо шарю, т.к. инфы в инете мало. Пж, без хейта.

Что такое батники и с чем их едят

Пакетный файл или в простонародье батник — это файл, который запускает командную сроку или сокращенно cmd, которая построчно интерпретирует команды, записанные в нем. Подробнее смотрите на https://ru.wikipedia.org/wiki/Пакетный_файл.

Первая программа и основные команды

Чтобы сделать батник, нужно сначала создать текстовый файл с именем test и изменить расширение c .txt на .bat. О том, как можно это сделать, читайте здесь: https://remontka.pro/file-extensions. У вас должен появиться файл с такой иконкой:

test.bat

Нажимаем на него ПРАВОЙ кнопкой мыши. Должно появиться диалоговое окно. Нажмем «Открыть». Должен открыться блокнот, пишем:

@echo off
echo Hello world!
pause

В 1-ой сроке («@echo off») префикс ‘@ ‘ означает, что команда не будет выведена на экран(попробуйте его убрать :-) ), сама же команда (echo) выводит текст следующий за ней(см. строку 2), НО, если подать строку «off», все последующие команды будут действовать так, как будто перед ними стоит префикс ‘@’, «echo on», соответственно, выключает этот режим. Чтобы вывести символ «%», его нужно дублировать, потом поймете почему :-), для вывода пустой строки поставьте «.» после «echo»
В 3-ей строке команда выводит строку «press any key to continue . . .» (если у вас русский язык — «Для продолжения нажмите любую клавишу . . .») и останавливает программу до нажатия любой клавиши.

Наводим красоту

Команда «rem»

не эта :)

не эта :)

не делает ничего и служит комментарием к коду

rem Это самая лучшая прога в мире!!!!!

Код включает русские символы и другие из ascii(например: «╬▓☼», можно скопировать с http://pascalguru.ru/psevdograf.html), иначе ascii символы превратятся в кракозябры:

chcp 65001

Следующий код код работает, как команда «pause», но ничего не выводит на экран и не реагирует на нажатие клавиш(я потом объясню, как это работает).

:m
goto m

А этот — меняет заголовок окна на «name»

Заголовок окна

Заголовок окна
title name

Эта команда меняет цвет фона и текста, вместо a и b можно поставить любые шестнадцатеричные цифры(команда не сработает если a = b) см. таблицу ниже. Запись c одной буквой «а» аналогично записи «0a»

color ab
Таблица

Таблица

Эта — досрочно завершает программу

exit

Переменные

Создать переменную можно с помощью команды set, синтаксис объявления следующий: P.S. это не совсем переменные, это скорее макросы (для тех к кто не знает C/C++ это именованный кусочек кода, имя которого заменяется на этот кусочек кода)

set a=Hello world

Если после «set» добавить флаг «/a» то:

  1. Переменной задастся значение выражения, а не его текст, например:

    set a=2+2
    > 2+2
    set /a a=2+2
    > 4
  2. Переменной можно присвоить ТОЛЬКО числовое значение

Чтобы обратиться к переменной, нужно окружить ее символами «%» (так %name%), пример кода:

set /a a=%b%+%b%
echo %a%

Подробнее о переменных

Если добавить флаг «/p», то выводиться значение после символа «=», а переменной задается введенное значение(запустите этот код:)

@echo off
set /p a=Enter str
echo %a%
pause

следующий код вырезает строку от символа номер «a» до символа номер «b» НЕ включительно(счет идет с нуля, отрицательные числа — счет с конца от единицы). Если аргумент один, то он присваивается числу «b», а «a» = 0

%str:~a,b%

следующий заменяет подстроки «a» в строке на строки «b»:

%str:a=b%

Циклы и условия

Цикл можно создать с помощью команды «for», синтаксис следующий:

for %%i in (a b c) do (
		cmd
)

или такой

for %%i in (a b c) do cmd

(a b c) это список (не обязательно из 3-х элементов) и переменная %%i (нужно ставить символ после процентов, а не между) по очереди проходит по значениям в списке

Если добавить флаг «/l», то переменная в первый раз будет равна «a». К ней каждый раз будет прибавляться «b», пока она не станет больше «c»(тут размер ДОЛЖЕН равняться 3)

запустите этот код, тут все наглядно

@echo off
chcp 65001
echo Начало
for /l %%i in (1 1 10) do echo %%i
echo Конец
pause

Команда if выполняет код, если условие верно (или если поставить not после if, когда НЕ верно), вот операторы сравнения:

P.S. строки нужно брать в кавычки «%str%»==»Hello»

equ(==)

=

neq

lss

<

leq

gtr

>

geq

пример кода:

@echo off
set /p a=Enter number
if a gtr 0 echo positive else\
if a equ 0 echo 0 else echo negative
pause

в 3-ей строке, если «a» > 0 выводиться «положительный»(на английском :-) ), если равен — 0,в 4-ой если меньше — «отрицательный»

символ «\» означает, что команда продолжается на следующей строке

Метки

Создадите файл start.bat в той же папке, где и test.bat, напишите в нем:

test.bat 2 2

Мы запустили батник, НО подали в него аргументы 2 и 2. Чтобы к ним обратиться, нужно написать %n, где «n» — номер аргумента, считая от одного(не от нуля), вот код, считающий сумму первого и второго аргумента (их может быть от нуля до 9-и):

@echo off
set /a res=%1+%2
echo res
pause

Метка — это именованное место в коде, она создается с помощью команды «:name»

А этот переходит на метку :m и продолжает выполнение, начиная с нее

rem куча кода
:m
rem куча кода
goto m
rem куча кода

И в завершение статьи, хочу сказать о команде call. Она превращает в последующей команде «%%» в «%», а переменные — на их значения. Пример использования:

call echo %%str:~%a%,%b%%%

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Contra 009 не запускается windows 10
  • Wsl2 windows 10 установка ubuntu
  • Программа для кастомизации меню пуск windows 10
  • Как попасть в биос на windows 10 через командную строку
  • Battle net не устанавливается на windows 10