Incode Systems Home Page Incode Systems, Inc.


Batch Files



Batch files are text files with a .BAT extension. You may create batch files with NotePad or any other other program that edits plain text. Note that while many word processing programs display plain text on the screen, the files they save may not be plain text. An easy way to tell if your favorite editor is saving plain text is to load the file with NotePad, or use the command TYPE from a command prompt to display the file. It should look just as it did in the editor; if not check to see if there is a File / Save As menu selection that includes text file (*.txt) as a option.

Writing Batch files is really high level programming. With the right batch programs you can even write entire applications with batch files.

Batch files may be executed at a command prompt just like a program by typing the name of the batch file, or you may set up a Windows shortcut with the name of the batch file on the command line.

In their simplest form, batch files may be used to just execute more than one program in sequence.

Environment Variables

Batch files may access variables in the environment. The environment is a block of memory that programs and batch files may use to store variable values. The operating system initializes a number of variables that are useful within a batch file. For example, the variable TEMP contains the path to a direcotry that may be used by programs and batch files to store temporary files. Type SET at a newly opened command prompt to see a list of the environment variables that have been setup by the operating system or programs that have been installed. If the list scrolls off the screen, you may view them all by typing:

SET | MORE

You can also display a partial list by including a variable name prefix. For example:

SET A

returns only the variables which start with the letter A. You may create your own initialized environment variables. Search Windows help for "environment variables" to see how.

The SET command may be used in a batch file to assign a value to a variable name, like this:

SET MyVariable=MyValue

After a variable is assigned it may be used (dereferenced) in a batch by surrounding the variable name with percent signs, like this:

ECHO %MyVariable%

References to variables are case insensitive, so %MyVariable% is the same as %myvariable%. When an instance of the command interpreter (command prompt) or any other program is opened, a copy of the global environment is made for the program. Changes made to this copy of the environment do not change the global environment. The SETLOCAL and ENDLOCAL commands may be used within a batch file to localize environment variables. SETLOCAL may also be used to temporarily enable Command Extensions (type SETLOCAL /? for details). Variables assigned after SETLOCAL are local to the batch; ENDLOCAL restores the environment to what it was before the SETLOCAL command. Windows assigns a number of variables to the global environment that are inherited by all processes. These variables include the USERNAME, USERPROFILE path, and windir (the Windows directory), allowing the construction of batch files that can run by different users or on different workstations. Type SET at a command prompt to display all the environment variables.

The SET command may also be used to check for environment variables that begin with a sequence of 1 or more letters:

REM List environment variables beginning with My
SET My

calculate a value:

REM Add 1 to A
SET /A A=%A% + 1

check if a value is a number:

REM Check to see if value of A is a number
REM Note: If A is a single token (word), ERRORLEVEL is 0, but B=0
SET A=Not a number
SET B=%A%
IF ERRORLEVEL 1 (
ECHO Not a number
) ELSE (
IF "%B%"=="0" (
ECHO Not a number
) ELSE (
ECHO Is a number
)
)

(type SET /? for more information).

Environment variable substring examples:

SET V=1234567890
SET A=%V:~0,2%
ECHO %A%
12
SET B=%V:~3,2%
ECHO %B%
45
SET C=%V:~2%
ECHO %C%
34567890
SET D=%V:~-2%
ECHO %D%
90
SET E=%V:~0,-4%
ECHO %E%
123456

(note: A and B work for Windows NT 4.0 and up, C and D work for Windows 2000 and up).

IF and FOR may be used to execute multiple lines in a batch like this:

FOR %%I IN (*.*) DO (
SET A=%%I
SET B=%A:~0,1%
ECHO %B%
)

The problem with the statement above is that ECHO %B% will only echo the value of B at the time the entire statement is executed because %B% is expanded just once when the statement is executed.

On Windows 2000 and up, this may be used:

SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%I IN (*.*) DO (
SET A=%%I
SET B=!A:~0,1!
ECHO !B!
)
SETLOCAL DISABLEDELAYEDEXPANSION

(note the exclamation point is used to immediately dereference variables, any variable deferenced with % is dereferenced once before the statement is executed).

This feature may also be used to return the value assigned to the variable the name of which is contained in another variable or batch parameter.

SETLOCAL ENABLEDELAYEDEXPANSION
SET Var2=2
SET Var1=Var2
ECHO This is the value of Var2: !%Var1%!
SETLOCAL DISABLEDELAYEDEXPANSION


On Windows 2000 and up, SET /P may be used to set an environment variable using the contents of a file:

SET /P V= (note: only the first line in myfile.txt is used to set the value of the variable. Piping the output of a command to SET does not work).

Saving variables between batch runs

Batch files may save the environment variables they use between executions of the batch like this:

OFF
SETLOCAL
REM Load variables
IF EXIST MyVars FOR /F %%F IN (MyVars) DO SET %%F

REM (Batch file steps here)
IF "%$RunCount%"=="" (SET $RunCount=1) ELSE (SET /A $RunCount=%$RunCount% + 1)
ECHO $RunCount=%$RunCount%
PAUSE

REM Save variables
SET $>MyVars
ENDLOCAL

In the example above, we have used $ as a prefix for all the variables used within the batch, since it is unlikely that character would be used by the operating system or another program. The FOR statement executes the SET command for every line in the file named MyVars. After the batch executes, the SET $>MyVars saves all the variable names beginning with $ to the file named MyVars. This technique cam be very useful for batches that run in the STARTUP folder every time the computer is logged in. Just right-click on the Start and select Open from the menu, open the Programs folder, then the Startup folder. Right-click in the folder and select New, then Shortcut and enter the full path to your batch file.

The technique outlined above can also be used to share variables among multiple batch files.
Batches may also CALL other batches:

PROG1
CALL BAT2.BAT
PROG2

After PROG1 runs, BAT2 is run. When BAT2 finishes, the calling batch resumes with PROG2. The called batch shares the same environment with the calling batch. So, changes to the environment made by the called batch are seen by the calling batch.

PROG1
BAT2.BAT
PROG2

However, in the example above, after PROG1 runs, BAT2 is run and does not return to the first batch when it completes.

If Command Extensions are enabled, CALL may also be used to run subroutines within a batch file. GOTO :EOF resumes execution on the line following the CALL to the subroutine. When used outside the context of a CALL, GOTO :EOF may be used to exit a batch.

@ECHO OFF
ECHO %%1=%1
ECHO %%2=%2
CALL :MySub SubParm1 SubParm2
ECHO Returned from MySub
ECHO %%1=%1
ECHO %%2=%2
GOTO :EOF

:MySub
ECHO Now running MySub
ECHO %%1=%1
ECHO %%2=%2
GOTO :EOF

In the example above, MySub is executed by CALL with Parm1. When within MySub, %1, %2,..%9 refer the parameters on the CALL line to the subroutine. GOTO :EOF returns to the line following the CALL and %1 now refers to the parameters used to run the whole batch. The GOTO :EOF encountered outside of the context of a CALL to a subroutine exits the entire batch.

Normally, when a command line program in a batch file is executed, the batch waits for the program to end before continuing with the next command in the batch (the program is run synchronously). However, if the program is a Windows GUI (Graphical User Interface) program, the batch may not wait for the program to end (the program is run asynchronously). This behavior may vary with the version of the operating system and the configuration. The START command may be used to force whether a program is run synchronously or asynchronously. To force a batch to wait for a GUI program to close before continuing, use START with the wait option (START /W). To force a batch to continue without waiting for the program to close, use START without the wait option.

The working directory when a batch file runs may be critical for the batch to run correctly. If a batch is run from a shortcut, the working directory may configured in the shortcut. If running a program or another batch from a batch file, the CD or CHDIR command may be used to change the working directory prior to execution. The PUSHD and POPD commands may be used to save and restore the current directory when running a process that might change the working directory. PUSHD saves the current directory and changes to the directory on the command line. POPD restores the current directory saved by PUSHD. A period is used to refer to the current working directory and two periods refers to the parent directory of the current working directory. So, PUSHD . may be used to save the current working directory before CALLing a batch that changes to another directory and POPD executed after the CALLed batch will restore the working directory. If Command Extensions are enabled, PUSHD may also be used with UNC paths. The example below will temporarily map a drive letter to the sharename on the given servername.

PUSHD \\servername\sharename\path

POPD will restore the current directory and disconnect the temporary drive map.

Each line in a batch file is a statement which may be a batch command, a label, an internal DOS command or an external program. DOS provides a number of command line utility programs.

Lines in a batch which start with REM (remark) are generally ignored, with the exception of redirection. For example:

REM Here is my remark>redirect.txt

In spite of the fact that the line above is preceeded with REM, the redirection will create an empty file name redirect.txt.

Normally you would not use redirection in a line that was a comment, however, another reason to comment a line in a batch file is to temporariliy disable it. If the line contains redirection, REM will not do the job. Instead do this:

::DisabledCommand.exe>redirect.txt

The colon character is the prefix for a label, so when the command processor encounters a line that starts with a colon, it is ignored, unless the command processor is searching for the label. By using two colons, the line will not be considered a label. This method also processes faster than a REM.

DOS Commands

Note: You may see your DOS version's usage of the internal commands by clicking on the commands listed below. This will open a DOS windows, display the usage and wait for keystroke to close the window. Be sure to open only one window at a time. The internal and external commands listed correspond to version 7.0. If you are running an older version of DOS, or the command file is not installed on your computer, you will see the message:
Bad command or file name.

Internal DOS Commands are:

BREAK
CALL
CD
CHCP
CHDIR
CLS
COPY
CTTY
DATE
DEL
DIR
ECHO
ERASE
EXIT
FOR
GOTO
IF
LFNFOR
LOADHIGH
LOCK
MD
MKDIR
PATH
PAUSE
PROMPT
RD
REM
REN
RENAME
RMDIR
SET
SHIFT
TIME
TYPE
UNLOCK
VER
VERIFY
VOL

External DOS Commands are:

ATTRIB
CHKDSK
CHOICE
DEBUG
DELTREE
DISKCOPY
DOSKEY
EDIT
EXTRACT
FC
FDISK
FIND
FORMAT
KEYB
LABEL
MEM
MODE
MORE
MOVE
MSCDEX
NLSFUNC
SCANDISK
SHARE
SORT
START
SUBST
SYS
XCOPY

For usage on each of internal or external commands, type the command followed by /? at a command prompt. For example:

ECHO/?

will display the usage for ECHO.

To find external commands look in the C:\DOS directory, or the C:\WINDOWS\COMMAND directory and follow the same procedure to discover the usage for the command.

Note: Incode Systems offers the following batch utilities which have the same name as DOS utilities:

SORT
MORE

These utilities are designed to replace the DOS program with the same name and have the same base usage and syntax, but offer extended functionality and/or performance. In order to make sure the Incode Systems version of the program runs (and not the DOS version), make sure that the Incode Systems version is in a path that preceeds the DOS command path in your PATH statement in the environment table. This is the preferred method. Other methods are deleting or renaming the DOS version of the program file (a disadvantage is you have to remember to do this each time you reinstall DOS (or Windows 95), or every time you use these programs, include a fully qualified path in front of the program name.

To execute a program in a batch, simply enter the program name on the left end of a line. If the program requires parameters on the command line, these may be entered to the right of the program name.

Batch files may be passed parameters on the command line which invokes the batch. Within the batch, these parameters may be referenced by %1 %2 %3 etc., (through 9) where %1 is the first parameter on the command, %2 the second, and so on. The SHIFT batch command may be used to reference more than 9 parameters. When SHIFT is executed, the first parameter is discarded, and the second becomes %1, etc. Also, the %0 parameter is the name of the batch itself. In Windows 95, command line parameters may be delimited (separated) by a space, comma, or semicolon. If a single parameter contains embedded spaces, you may surround it with double quotes. Double quoted parameters include the double quotes when dereferenced. If the parameter itself contains a double quote, escape it by doubling the double quote character. These doubled double quotes will also be contained in the dereferenced parameters. Prior to Windows 95, parameters were separated by spaces only. In addition, %* may be used to reference all parameters except %0 which were passed to the batch. The SHIFT command does not alter the contents of %*. For example, you could call another batch with all the parameters passed to the original batch like this:

CALL MyBat.bat %*

SHIFT Example:

:BEGIN
IF "%1"=="" GOTO END
PROG1 %1
SHIFT
GOTO BEGIN

:END

If the example above is in a file named BAT1.bat, the following command line would execute the command lines shown below it:

BAT1 Parm1 Parm2 Parm3 Parm4 Parm5 Parm6
PROG1 Parm1
PROG1 Parm2
PROG1 Parm3
PROG1 Parm4
PROG1 Parm5
PROG1 Parm6

Parameters may be dereferenced with special prefix characters to return modified file names:

%~f1 - expands %1 to a fully qualified path name
%~d1 - expands %1 to a drive letter only
%~p1 - expands %1 to a path only
%~n1 - expands %1 to a file name only
%~x1 - expands %1 to a file extension only
%~s1 - expanded path contains short names only
%~$PATH:1 - searches the directories listed in the PATH
environment variable and expands %i to the
fully qualified name of the first one found.
If the environment variable name is not
defined or the file is not found by the
search, then this modifier expands to the
empty string

In Windows 2000 and newer:

%~1 - expands %1 removing any surrounding double quotes (")

For more information, see usage on the FOR command.

To remove a given number of characters from the beginning of an environment variable:

SET A=123456789
SET A=%A:~2%
ECHO A=%A%
A=3456789

For more information, see usage on the SET command.

The IF batch command may be used to compare strings or with the ERRORLEVEL syntax to either branch to another place in a batch to conditionally execute a command line. Type IF /? for more information.

ECHO is an internal DOS command which controls whether batch lines are "echoed" to the screen as they are executed. ECHO ON causes lines to be echoed, ECHO OFF causes them to NOT be echoed. The "at" character (@) may also be used at the beginning of a line to cause it to not be echoed. ECHO is ON by default. ECHO Message displays Message, even if ECHO is OFF

To ECHO a blank line, use ECHO.

For example:

IF "%1"=="HOWDY" GOTO LABEL2
ECHO HOWDY is not parameter 1
GOTO MOREBAT
:LABEL2
ECHO HOWDY is parameter 1
:MOREBAT

The statement above checks to see if the first parameter on the batch file command line is HOWDY, if it is, the batch jumps to LABEL2, if not it continues with the next line.

Using double-quote characters (ASCII 34) to delimit a parameter in an IF statement can cause a problem when the batch is passed a parameter which is double-quoted. If a parameter passed to a batch file contains embedded spaces, it must be surrounded by double-quote characters. The parameter value dereferenced within the batch file contains the double-quote characters, so they are effectively double-quoted a second time when IF "%1" is used. The batch file will exit with a message containing was unexpected at this time. To avoid this problem, you can use a different character to delimit the parameter marker. For example:

IF `%1`==`HOWDY` GOTO LABEL2

The character used to surround %1 is a leading quote character (ASCII 96). There is nothing special about ASCII 96, I just selected it because it looks like a quote character and it is not commonly used.

IF %1. == HOWDY. GOTO LABEL2

Ending each string with a period is another way to avoid this problem.

ELSE may also be used. Here is a one line IF with ELSE followed by a multiline IF ELSE:

IF %1. == HOWDY. (ECHO Yes) ELSE ECHO No

IF %1. == HOWDY. (
ECHO This and
ECHO That
) ELSE (
ECHO Other and
ECHO Another
)


Under Windows 2000 and newer, this will work:

IF "%~1"=="HOWDY" (ECHO Yes) ELSE ECHO No

PAUSE is an internal DOS Command which displays:

Press any key to continue . . .


and waits for a keystroke before continuing. If you want to branch based on which key is pressed, use GETKEY or CONFIRM

FOR may be used to run a program multiple times.

FOR examples:

FOR %%F IN (*.TXT) DO PROG1 %%F
FOR %%F IN (First,Second,Third) DO PROG1 %%F
FOR %%F IN (D:\MyPath\*.txt) DO PROG1 %%F

The first FOR statement above runs the program named PROG1 once for each instance of a file with a TXT extension. Note that %%F contains two percent signs. That is because a percent sign used in a batch must be doubled unless it refers to a parameter (%1 - %9). The same statement may be run from a command prompt with a single percent sign. If there are three files matching *.txt in the current directory: 1.txt, 2.txt, and 3.txt, the following command lines would be executed:

PROG1 1.TXT
PROG1 2.TXT
PROG1 3.TXT

The second FOR statement runs the program named PROG1 three times with the parameters listed. Note that parameters listed this way need not be file names. The following command lines would be executed:

PROG1 First
PROG1 Second
PROG1 Third

The third FOR statement would run the following command lines if there were three TXT files named 1.TXT, 2.TXT, and 3.TXT:

PROG1 D:\MyPath\1.txt
PROG1 D:\MyPath\2.txt
PROG1 D:\MyPath\3.txt

If Command Extensions are available in your version of the OS and are enabled, the FOR statement can do much more (run FOR /? | MORE for details)

Command Extensions FOR example:

Suppose you have a collection of files with the following names:

BOOK1_001.txt
BOOK1_002.txt
BOOK1_003.txt
.
.
.
BOOK200_001.txt
BOOK200_002.txt
BOOK200_003.txt

Now, suppose you want to rename them so the number in the file name appears first. The following line in a BAT file will perform the commands that follow:
FOR %%v IN (*_*.txt) DO FOR /F "tokens=1-3 delims=_." %%i IN ("%%v") DO REN "%%v" "%%j_%%i.%%k"

REN "BOOK1_001.txt" "001_BOOK1.txt"
REN "BOOK1_002.txt" "002_BOOK1.txt"
REN "BOOK1_003.txt" "003_BOOK1.txt"
.
.
.
REN "BOOK200_001.txt" "001_BOOK200.txt"
REN "BOOK200_002.txt" "002_BOOK200.txt"
REN "BOOK200_003.txt" "003_BOOK200.txt"

The FOR command may be used to run another program and process the output:

REM ECHO all environment variables
FOR /F "delims=" %%i IN ('set') DO @echo %%i
REM ECHO just the variable name part of all environment variables
FOR /F "delims==" %%i IN ('set') DO @echo %%i
REM If single quotes are needed in the command line, use the usebackq option:
FOR /F "usebackq delims==" %%i IN (`set`) DO @echo %%i
REM Note: the quotes surrounding set are backquotes (ASCII 96),
REM (above tab key on most keyboards).

Batch file programming tips

How to detect if a drive letter is unavailable:

VOL F: >NUL 2>NUL
IF ERRORLEVEL 1 GOTO NO_F

The internal VOL command will set ERRORLEVEL to 1 if the drive is not mapped or the drive is not available, like a DVD drive with no disk in the drive. Redirection is used to hide the output of the VOL command as well as any error messages.

For UNC names, use DIR, like this:

DIR \\server\>NUL 2>NUL
IF ERRORLEVEL 1 GOTO NO_SERVER

How to detect if a path exists:

IF EXIST may be used to check for the existence of a file, like this:

IF EXIST FileName.ext GOTO Found

To check for the existence of a directory, check for NUL in the path, like this:

IF EXIST MyPath\NUL GOTO Found


How to change the working directory to the BAT file directory:

When you write a batch file to process files which are dropped on the batch file in Windows Explorer (or a shortcut to your batch file), the working directory is likely to be the Windows, not the directory where the batch file exists or the file that was dropped. If your batch contains other files needed to process the file that was dropped, you will need to change the working directory to the directory where the batch file exists.

if not "%cd%"=="%~dp0" cd /d %~dp0