DOS -
Persistent Variables
Want to remember the state of your
DOS batch over different sessions?
Want to make you DOS batch
available in the network but store user preferences local?
Persist variables is what you
need.
Ideally you somehow mark your
variables to be persistent and have one function to store all persistent
variables and one function to restore persistent value back into the
variables. Learn here how to do this.
2 Mark
Variables to be Persistent
3 getPersistentVars
- Function
4 savePersistentVars
- Function
5 restorePersistentVars
- Function
6 Example
- Persistent Variables
1
Example Batch to
Start With
|
|
Description |
Copy the following code into an empty batch file (e.g.: "DosTips.bat"). Get familiar with it by executing it and
changing some of the variables when prompted.
Close the application using the "q" option and then run it again. As you will see all variable changes from
the previous run are lost. |
Code |
@echo off rem.--- Prepare the Command Processor --- SETLOCAL ENABLEEXTENSIONS SETLOCAL ENABLEDELAYEDEXPANSION rem.--initialize the variables set color=1e set lines=20 set title=Hello World : rem.--apply the variable settings color %color% title %title% MODE CON: LINES=%lines% COLS=80 rem.--show current settings echo.Currently the variables are: echo. echo. color=%color% echo. lines=%lines% echo. title=%title% echo. echo. rem.--let the change the variables echo.Assign new values, for example enter: echo. echo. color=2e echo. lines=40 echo. title=HI THERE echo. set cmd= set /p cmd=Or
enter q to quit: if /i
"%cmd%"=="q" (
GOTO:EOF ) rem.--execute the SET command and loop back SET %cmd% GOTO: |
|
This batch program uses three variables color, lines, and title. The user can change the variables. However after closing the application with
‘q' all settings are gone. Our goal is to have all three variables
persistent so that when running the batch next time the previews setting show
up. |
2
Mark Variables to be
Persistent
|
|
Description |
The challenge is to mark a variable as persistent but
still keep the code looking good and maintainable. Changing the SET command to a function call
where the variable gets initialized the first time meets the requirement: |
Code |
call:setPersist color=1e call:setPersist lines=20 call:setPersist title=Hello World |
|
The setPersist function will just do what the set function did,
assigning a value to the variable. |
Code |
:setPersist -- to be called to initialize persistent variables : -- %*: arguments for the SET
command set %* GOTO:EOF |
|
Of course just replacing the SET command with a call to setPersis doesn't make the
variable persistent, but we can write another function now that parses the
batch file for all lines containing the call:setPersist command and automatically persist the corresponding
variables. |
3
getPersistentVars - Function
|
|
Description |
The getPersistentVars function
parses its owning batch file for lines calling the setParsist function and
collects the associated variables in a comma separated list. The comma speared list of strings can easy
be parsed later using the FOR
function. |
Code |
:getPersistentVars
-- returns a comma separated list of persistent variables : -- %~1: reference to return
variable SETLOCAL set retlist= set parse=findstr
/i /c:"call:setPersist"
"%~f0%"^|find /v "ButNotThisLine" for /f "tokens=2 delims== " %%a in ('"%parse%"') do (set retlist=!retlist!%%a,) ( ENDLOCAL & REM RETURN VALUES
IF "%~1" NEQ "" SET %~1=%retlist% ) GOTO:EOF |
How it works |
The findstr command applied to "%~f0%" (the
batch file itself ) filters
all lines having the "call:setPersist"
command in it, which is what we want.
In addition it finds the line that searches for the "call:setPersist"
string within the getPersistentVars
function itself, which we don't want.
So we need to pipe the findstr output into another find command that filters the unwanted output. The resulting parser code will be stored
into the parse variable and is
being used in the FOR command of
the next line. The FOR command
splits each line found by the parse command using " " (space) and "="
(assignment operator) as delimiters.
This way the first token found will always be the string "call:setPersist" and
the second token will always be the variable name that we are looking for. The variable name will then be added to the return list
called retlist
adding a trailing comma in order to separate the variable names from each
other. |
4
savePersistentVars - Function
|
|
Description |
The savePersistentVars function
creates an executable batch file having a SET command for each variable to be
persisted. The values can easily be
restored by executing this batch file. |
Code |
:savePersistentVars
-- Save values of persistent variables into a file : -- %~1: batch file name to
save to SETLOCAL echo.>"%~1" call :getPersistentVars
persvars for %%a in (%persvars%)
do (echo.SET %%a=!%%a!>>"%~1") GOTO:EOF |
How it works |
The SETLOCAL
call ensures that changes to the persvars variable is invisible outside the function. A corresponding ENDLOCAL is implicitly being executed by the GOTO:EOF command at
the end of the function. The echo.>"%~1"
command creates an empty new file whether or not one already exist. The call to getPersistentVars
returns the comma separated list of persistent variables into the persvars
variable. The persvars variable is then being parsed by the FOR command which adds a SET
<VAR>=<CURRENTVALUE> entry for each persistent
variable to the new created file. |
5
restorePersistentVars - Function
|
|
Description |
The restorePersistentVars
function shall simply execute the batch file that stores the commands to
restore the persistent variables. |
|
:restorePersistentVars
-- Restore the values of the persistent variables : -- %~1: batch file name
to restore from if exist "%FilePersist%"
call "%FilePersist%" GOTO:EOF |
6
Example -
Persistent Variables
|
|
Description |
Some modifications have been made to the previous example
in order to make the variables for the color, the number of lines, and the
window title persistent. The relevant
modification are shown in bold below. Copy the new code into an empty batch file (e.g.: "DosTips.bat"). Get
familiar with it by executing it and changing some of the variables when
prompted. Close the application using
the "q" option and reopen it. As you
will see the variables show the values as set in the previous run. |
Code |
@echo off rem.--- Prepare the Command Processor --- SETLOCAL ENABLEEXTENSIONS SETLOCAL ENABLEDELAYEDEXPANSION rem.--define the filename where persistent variables get storred rem. just add a + to
the name of THIS file, i.e. "DosTips.bat"
- "DosTips+.bat" set FilePersist=%~dpn0+%~x0 rem.--initialize the variables call:setPersist color=1e call:setPersist lines=20 call:setPersist title=Hello World rem.--restore the persistent variables call:restorePersistentVars "%FilePersist%" : rem.--apply the variable settings color %color% title %title% MODE CON: LINES=%lines% COLS=80 rem.--show current settings echo.Currently the variables are: echo. echo.
color=%color% echo.
lines=%lines% echo.
title=%title% echo. echo. rem.--let the change the variables echo.Assign new values, for example enter: echo. echo.
color=2e echo.
lines=40 echo.
title=HI THERE echo. set cmd= set /p cmd=Or
enter q to quit: if /i
"%cmd%"=="q" (
call:savePersistentVars "%FilePersist%"
GOTO:EOF ) rem.--execute the SET command and loop back SET %cmd% GOTO: :----------------------------------------------------- :-- functions to be added below
here :----------------------------------------------------- :setPersist
-- to be called to initialize persistent variables : -- %*: set command arguments set %* GOTO:EOF :getPersistentVars
-- returns a comma separated list of persistent variables : -- %~1: reference to return
variable SETLOCAL set retlist= set parse=findstr
/i /c:"call:setPersist"
"%~f0%"^|find /v "ButNotThisLine" for /f "tokens=2 delims== " %%a in ('"%parse%"') do (set retlist=!retlist!%%a,) ( ENDLOCAL & REM RETURN VALUES
IF "%~1" NEQ "" SET %~1=%retlist% ) GOTO:EOF :savePersistentVars
-- Save values of persistent variables into a file : -- %~1: file name SETLOCAL echo.>"%~1" call :getPersistentVars
persvars for %%a in (%persvars%)
do (echo.SET %%a=!%%a!>>"%~1") GOTO:EOF :restorePersistentVars
-- Restore the values of the persistent variables : -- %~1: batch file name
to restore from if exist "%FilePersist%" call "%FilePersist%" GOTO:EOF |
|
After closing the batch application
using the "q" option a new file is being created in the same directory as the
batch application itself. The new created
batch file list all persistent variables, i.e.: |
Output |
SET color=2e SET lines=20 SET title=Hi There |
Note |
From here on it's easy to add more persistent
variables. Simply add another
variable to the "initialize the variables" section of the batch file, e.g.: |
Code |
call:setPersist myvar=myvalue |