Batch files

BATCH FILE IN DOS
Batch files
Parameters
A parameter (or argument) is any value passed into a batch script:
C:> MyScript.cmd January 1234 "Some value"
Parameters may also be passed to a subroutine with CALL:
CALL :my_sub 2468
You can get the value of any parameter using a % followed by it's numerical position on the
command line. The first item passed is always %1 the second item is always %2 and so on
Cooltipz
%* in a batch script refers to all the arguments (e.g. %1 %2 %3 %4 %5 ...%255)
Filename Parameter Extensions
When a parameter is used to supply a filename then the following extended syntax can be
applied:
we are using the variable %1 (but this works for any parameter)
%~f1 - expands %1 to a Fully qualified path name - C:\utils\MyFile.txt
%~d1 - expands %1 to a Drive letter only - C:
%~p1 - expands %1 to a Path only - \utils\
%~n1 - expands %1 to a file Name, or if only a path is present - the last folder in that path
%~x1 - expands %1 to a file eXtension only - .txt
%~s1 - changes the meaning of f, n and x to reference the Short name (see note below)
%~1 - expand %1 removing any surrounding quotes (")
%~a1 - display the file attributes of %1
%~t1 - display the date/time of %1
%~z1 - display the file size of %1
ARTICLE BY MOHIT GUPTA
Page 1
BATCH FILE IN DOS
%~$PATH:1 - search the PATH environment variable and expand %1 to the fully qualified
name of the first match found.
The modifiers above can be combined:
%~dp1 - expands %1 to a drive letter and path only
%~nx2 - expands %2 to a file name and extension only
When writing batch scripts it's a good idea to store parameter values in a variable using the
SET command, the rest of the script can then refer to the easy-to-read name SET
_LogFile=%~dp1 This will also make life easier if you later need to change around the order
of the parameters.
Note on short file/folder names:
There is a bug involving the ~s option - the displayed output may be wrong if the current
directory name is not the same as the 8.3 version of the directory.
A workaround is to run command.com /c rem , which will change the current directory to 8.3
Cooltipz
e.g. if the current directory is C:\Program Files\ you will see the bug
if the current directory is C:\progra~1\ it will work fine (but then you wont see the long
name)
more here
FOR command parameters
The FOR command creates parameters which are identified with a letter rather than a
number. These are easily confused with the parameter modifier letters described above.
Therefore when using FOR it's best to avoid the letters (a, d, f, n, p, s, t, x, z), apart from
making code easier to follow, this can avoid problems when running under NT 4 and
Windows 2000:
%0 - the Batch Script itself
You can get the pathname of the .CMD script itself with %0
If the script is stored on a network share, it may be accessed directly from the UNC share or
via a mapped drive.
You cannot set the current directory to a UNC path but you can refer to other files in the
same folder as the batch script by using this syntax:
CALL %0\..\SecondBatch.cmd
When the %0 variable is expanded in Windows XP, the result is enclosed in quotation marks.
Examples:
ARTICLE BY MOHIT GUPTA
Page 2
BATCH FILE IN DOS
Pass parameters from one batch to another:
MyBatch.cmd SMITH 100
Or as part of a CALL :
CALL MyBatch.cmd SMITH 100
Passing values from one part of a script to another
Using CALL to jump to a subroutine
CALL :s_staff SMITH 100
Calling a subroutine from a FOR command
FOR /F %%G IN ('DIR /b *.*') DO call :s_subroutine %%G
"A gift is pure when it is given from the heart to the right person at the right time and at the
right place, and when we expect nothing in return" - The Bhagavad Gita
Cooltipz
ARTICLE BY MOHIT GUPTA
Page 3
BATCH FILE IN DOS
Variables
Environment variables are mainly used within batch files, they can be created, modified and
deleted using the SET command.
Variables can be displayed using either SET or ECHO.
Variables have a percent sign on both sides: %ThisIsAVariable%
The variable name can include spaces, punctuation and mixed case: %_Another Ex.ample%
(n.b. Parameter Variables only have one % sign and are always one character long: %A )
Pass a variable from one batch script to another
Where one batch script CALLs another it is recommended that you SETLOCAL in both
scripts to prevent any possible naming conflicts, so each script should start with:
@ECHO OFF
SETLOCAL
Cooltipz
Then to pass a value back to the original calling script, finish the script with a line like:
ENDLOCAL & SET _output=%_variable%
In the line above %_variable% is a local variable used and visible within just that one batch
script
%_output% is an output variable that is passed back to the original calling script
Standard (built-in) Variables
Predefined environment variables
Typical value:
WinXP
Variable
Typical value:
Vista/2008
%ALLUSER
SPROFILE%
C:\Documents and Settings\All Users C:\ProgramData
%APPDATA
%
C:\Documents and
C:\Users\{username}\AppData\Roam
Settings\{username}\AppData\Roami
ing
ng
%CommonPr
ogramFiles%
N/A
C:\Program Files\Common Files
%COMPUTE
RNAME%
{computername}
{computername}
ARTICLE BY MOHIT GUPTA
Page 4
BATCH FILE IN DOS
%COMSPEC
%
C:\Windows\System32\cmd.exe
C:\Windows\System32\cmd.exe
%HOMEDRI
VE%
C:
C:
%HOMEPAT
\Documents and Settings\{username} \Users\{username}
H%
%LOCALAP
PDATA%
N/A
%PATH%
C:\Windows\System32\;C:\Windows C:\Windows\System32\;C:\Windows
\;C:\Windows\System32\Wbem
\;C:\Windows\System32\Wbem
%PATHEXT
%
.COM; .EXE; .BAT; .CMD; .VBS;
.VBE; .JS ; .WSF; .WSH;
C:\Users\{username}\AppData\Local
.COM; .EXE; .BAT; .CMD; .VBS;
.VBE; .JS ; .WSF; .WSH; .MSC
%ProgramDat
N/A
a%
C:\ProgramData
%PROGRAM
C:\Program Files
FILES%
C:\Program Files
%ProgramFile
C:\Program Files (x86)
s(x86)% 1
C:\Program Files (x86)
%PROMPT% $P$G
$P$G
%Public%
N/A
C:\Users\Public
%SYSTEMD
RIVE%
C:
C:
%SYSTEMR
OOT%
C:\Windows
C:\Windows
%TEMP%
and %TMP%
C:\Documents and
Settings\{username}\Local
Settings\Temp
C:\Users\{Username}\AppData\Loca
l\Temp
Cooltipz
%USERNAM
{username}
E%
{username}
%USERPRO
FILE%
C:\Documents and
Settings\{username}
C:\Users\{username}
%WINDIR%
C:\Windows
C:\Windows
1
Only on 64 bit systems, is used to store 32 bit programs.
By default, files stored under Local Settings do not roam with a roaming profile.
ARTICLE BY MOHIT GUPTA
Page 5
BATCH FILE IN DOS
%ERRORLEVEL% is a dynamic variable that is automatically set when a program exits.
Dynamic Variables
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 are computed each time the variable is expanded.
%CD% - expands to the current directory string.
%DATE% - expands to current date using same region specific 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.
%CMDEXTVERSION% - expands to the current Command Processor Extensions version
number.
Cooltipz
%CMDCMDLINE% - expands to the original command line that invoked the Command
Processor.
Note: you should not attempt to directly SET any of the dynamic variables above.
"Men may be convinced, but they cannot be pleased against their will. But though taste is
obstinate, it is very variable, and time often prevails when arguments have failed" - Samuel
Johnso
ARTICLE BY MOHIT GUPTA
Page 6
BATCH FILE IN DOS
Redirection
command
>
command
>> filename
APPEND into a file
command
<
Type a text file and pass the text to command
commandA
command
second
command
(command)
command
command
filename
filename
|
&
commandB
command
Redirect command output to a file
Pipe the output from commandA into commandB
Perform the first command & then perform the
2> filename
2> filename
> file 2>&1
> fileA 2> fileB
Redirect
Redirect
Redirect
Redirect
any error message
any CMD.exe error
output and errors
output and errors
2>&1 >filename
This will fail!
into a file
into a file
to one file
to separate files
Cooltipz
command
Redirect to NUL (hide errors)
command
command
2> nul
>nul 2>&1
NUL
command >filename 2> nul
(command) >filename 2> nul
errors
Redirect error messages to NUL
Redirect error and information messages to
Redirect info to file but suppress error
Redirect info to file but suppress CMD.exe
Note, any long filenames must be surrounded in "double quotes". A CMD error is an error
raised by the command processor itself rather than the program/command.
Redirection with > or 2> will overwrite any existing file.
You can also redirect to a printer with > PRN or >LPT1
To prevent any of the above characters from causing redirection prefix with a caret ^
Examples of redirection:
DIR >MyFileListing.txt
DIR /o:n >"Another list of Files.txt"
ECHO y| DEL *.txt
ECHO Some text ^<html tag^> more text
ARTICLE BY MOHIT GUPTA
Page 7
BATCH FILE IN DOS
MEM /C >>MemLog.txt
Date /T >>MemLog.txt
SORT < MyTextFile.txt
SET _output=%_missing% 2>nul
DIR C:\ >List_of_C.txt 2>errorlog.txt
FIND /i "Jones" < names.txt >logfile.txt
DIR C:\ >List_of_C.txt & DIR D:\ >List_of_D.txt
ECHO DIR C:\ ^> c:\logfile.txt >NewScript.cmd
(TYPE logfile.txt >> newfile.txt) 2>nul
"Change is good. You go first" - Scott Adams (Dilbert)
Cooltipz
ARTICLE BY MOHIT GUPTA
Page 8
BATCH FILE IN DOS
Conditional Execution
Syntax
An AND list of commands has the form
command1
&& command2
command2 is executed if, and only if, command1 succeeds.
A single & will always execute both commands
command1 & command2
An OR list of commands has the form
command1
|| command2
command2 is executed if, and only if, command1 fails
Cooltipz
Example
COPY Z:\Oracle\TNSnames.ORA C:\Oracle\ || ECHO The Copy Failed
"Cooperation which needs consideration is a commercial contract, and not friendship.
Conditional cooperation is like adulterated cement which does not bind" - Mohandas K.
Gandhi
ARTICLE BY MOHIT GUPTA
Page 9
BATCH FILE IN DOS
Loops and subroutines
There are 2 ways to conditionally process commands in a batch file
IF xxx ELSE yyy - will conditionally perform a command (or a set of commands)
FOR aaa DO xxx - will conditionally perform a command several times (for a set of data, or
a set of files)
Either of these can be combined with the CALL command to run a subroutine like this:
@echo off
IF EXIST C:\pagefile.sys CALL :s_page_on_c
IF EXIST D:\pagefile.sys CALL :s_page_on_d
GOTO :eof
:s_page_on_c
echo pagefile found on C: drive
GOTO :eof
Cooltipz
:s_page_on_d
echo pagefile found on D: drive
Without the : a second batch file will be called ...
@ECHO off
IF EXIST C:\pagefile.sys CALL Second_Batch.cmd
If the code does not need to return then use the GOTO statement like this:
@ECHO off
IF EXIST C:\pagefile.sys GOTO s_page_on_c
ECHO pagefile not found
GOTO :eof
:s_page_on_c
ECHO pagefile found
To call a second batch file in a separate shell use CMD An important difference between
CALL and CMD is the exit behaviour if an error occurs.
@ECHO off
IF EXIST C:\pagefile.sys CMD /C Second_Batch.cmd
"I knew of one little DO loop that ran for 48 hours, cost $14,000 and did nothing" - Richard
Keeler
ARTICLE BY MOHIT GUPTA
Page 10
BATCH FILE IN DOS
Batch file Functions
Packaging up code into a discrete functions, each with a clear purpose is a very common
programming technique. Re-using known, tested code, means you can solve problems very
quickly by just bolting together a few functions.
The CMD shell does not have any documented support for functions, but you can fake it by
passing arguments/parameters to a subroutine and you can SETLOCAL use to control the
visibility of variables.
At first glance building a function may look as simple as this:
:myfunct
SETLOCAL
SET _var1=%1
SET _var2="%_var1%--%_var1%--%_var1%"
SET _result=%_var2%
ENDLOCAL
Cooltipz
but there is a problem, the ENDLOCAL command will throw away the _result variable and
so the function returns nothing.
:myfunct2
SETLOCAL
SET _var1=%1
SET _var2="%_var1%--%_var1%--%_var1%"
ENDLOCAL
SET _result=%_var2%
This version is getting close, but it still fails to return a value, this time because ENDLOCAL
will throw away the _var2 variable
The solution to this is to take advantage of the fact that the CMD shell evaluates variables on
a line-by-line basis - so placing ENDLOCAL on the same line as the SET statement(s) gives
the result we want:
:myfunct3
SETLOCAL
SET _var1=%1
SET _var2="%_var1%--%_var1%--%_var1%"
ENDLOCAL & SET _result=%_var2%
In examples above there are just 2 local variables (_var1 and _var2) but in practice there
could be far more, by turning the script into a function with SETLOCAL and ENDLOCAL
we don't have to worry if any variable names will clash.
In other words you can do this:
ARTICLE BY MOHIT GUPTA
Page 11
BATCH FILE IN DOS
@ECHO OFF
SET _var1=64
SET _var2=123
CALL :myfunct3 Testing
echo %_var1%
echo %_result%
goto :eof
:myfunct3
SETLOCAL
SET _var1=%1
SET _var2="%_var1%--%_var1%--%_var1%"
ENDLOCAL & SET _result=%_var2%
The use of SETLOCAL and ENDLOCAL is roughly equivalent to option explicit in Visual
Basic.
When working with functions it can be useful to use Filename Parameter Extensions against
the function name, %0 will contain the call label, %nx0 the file name, see Rob Hubbards blog
for an example. Note that if you have two scripts one calling another, this will not reveal the
location of the 'calling' script.
Cooltipz
“Cats are intended to teach us that not everything in nature has a function” - Garrison
Keillor
ARTICLE WRITTEN BY MOHIT GUPTA
FOR ANY QUERY CONTACT AT:
[email protected]
ARTICLE BY MOHIT GUPTA
Page 12