Batch files: Snippets 1

From The Uniform Server Wiki
Jump to navigation Jump to search

Batch Files:    Snippets 1 | First Free Drive

MPG UniCenter

MPG UniCenter

Batch file code snippets.

This is not really batch file specific more a general repository to dump things that I tend to forget. You may find these of use and worth a browse!

CALL

CALL is used to run another batch file within a batch file. When the batch file that is called is completed, the remainder of the original batch file is completed. Note if the batch file does not exist it will give an error message.

General DOS

DOS Console commands Comments
part of name folder/file Tab key Enter part of file or folder name press Tab key to complete (cycles) Note: Shift + Tab move back in list.
F7 key View command history
Ctrl and c Kills the batch file
Ctrl+s Toggle scroll window
start. Open current command-line folder in a Windows Explorer Window.
start.. Open folder above the current command-line folder in a Explorer Window.

Some useful batch-file commands

Batch Commands Comments
"G:\fred\mr fred.txt" Killer spaces wrap complete path in quotes
echo. Echo followed by period no space outputs Blank line
if exist file command If the file exists execute the command
if not exist file command If the file does not exists execute the command
nul All folders contain the null device file "Black hole"
command > nul Execute command sends whatever is output to black hole
command 2> nul Suppress error 2 output
if exist folder\nul Test existence of a folder
cd .. Move up one folder from the working folder
cd /d G:\fred Change working folder to fred on drive G:
pushd G:\fred Same as above (not sure if a pop is required!)
for %%variable In set Do statement Variable in for loop requires %% not a single %

Top

Current Working Directory

Uniform Server will run on any drive from any folder, simply double-click on the relevant batch file. If you call these batch files from another drive the chances it will not work. The problem is most likely due to the setting for the current drive. This is easily resolved using a very powerful batch command %~ I use this in conjunction with two other commands, before I expand on this do you really need to use it!

Environment variable manipulation

General format:

%VAR:str1=str2%

Expands VAR (any environment variable), substituting each occurrence of "str1" with "str2".

%VAR:str1=%

If "str2" is empty all occurrences of "str1" are deleted from the expanded VAR.

Substrings

%VAR:~position,number of characters to extract%

Note: First character position starts at zero

If VAR has a value of abcdefgh then:
%VAR:~2,4% would produce defg
%VAR:~0,1% would produce a

Note 1: If the number of characters to extract is not specified it defaults to the remainder after position.

Note 2: If either parameter is negative, position used is the length of the environment variable value added to the number of characters to extract.

%VAR:~-5% This would extract the last 5 characters of VAR.

%VAR:~0,-2% This extract all but the last 2 characters of VAR.

Top

Working directory

Suppose you have located (unzipped) Uniform Server on drive "D" in folder progz\uni1.

Open a command prompt and navigate to the Uniform Server folder for example type in D: and then cd progz\uni1 this is referred to as your Current Working Directory. Any relative paths in Server_Start.bat are referenced to this CD (current working directory or current folder they are the same thing).

From the command prompt type in Server_Start the operating system looks in the Current Directory to find the file and runs it.

Now back to the explorer window, when you double click on the file Server_Start.bat it opens a command prompt and should automatically set the current directory to that of the current batch file. However it may use the previous current working directory clearly a problem.

Test batch file: To check you have this problem create a test batch file test.bat copy the following lines and save it in the folder where the server start and stop files are located:

test.bat
echo off
echo =======================
echo Current path = %CD%
echo Real bat path = %~dp0
echo =======================
pause

It prints out the current path (Current Directory) using %CD% and the path where the batch file is located using %~dp0. On a local machine the only difference in paths will be a back-slash at the end for real batch path. If these are different then there is a problem.

If the paths are the same (apart from the back slash) you do not have a problem. Just for fun you can simulate the problem. Open a command prompt this normally defaults to c, type the full path including the file name for the test file e.g.
G:\UniServer3\Uniform Server\test.bat

Note because of the space in the file name you do need to wrap it in quotes. When run notice the paths are different, it's no joke and causes many problems..

You can use %~dp0 to change the current working directory, but if you want to run this say across file servers or even different drives you are not returned to the originating current working directory. This leads to confusion and problems. The ideal solution is to save old location, create a new working directory (where the batch file is located) execute your code when finished restore to old working directory.

Push and Pop, some real old micro terminology; push, saves where you came from and pop, zaps you back to where you came from, add this to where you think you are and you have a real solution.

Solution use pushd and popd
pushd %~dp0
....
batch file code
....
popd
  • pushd Pushes the Current Directory onto a memory stack (Where you came from).
  • %~dp0 This forces the CD to the current location of the batch file you are running. It includes the full path not just the drive letter (if its remote that’s included).
  • popd Restores the previously pushed directory.

Its not a panacea, however you do know the code you are running in your batch file will be relative to its real location, further you know where you came from hence can return to that known point.

Start every batch file with: pushd %~dp0 and End it with: popd

The solution is not backwards compatible with older OS's however from XP onwards should work.

Top

Current drive letter 1

To pick up the current drive letter (where the batch file resides) use:

How to obtain batch file drive letter
pushd %~dp0
set current_drive=%~d0
....
batch file code
....
popd

Note: Drive includes colon e.g W:

 

How to obtain batch file drive letter
pushd %~dp0
set current_drive=%~d0
set current_drive=%current_drive:~0,1%
....
batch file code
popd

Note: Drive letter only e.g W

Top

Current drive letter 2

If all your batch files are located on the same drive and not run from other batch files on different drives this solution by jacob lee is worth considering. I lifted this from the forum and reproduce as is:

using %CD% we can do a lot of things.

open cmd.exe and type "echo %CD%". it will show like "C:\Documents and Settings\jacob lee"

type "echo %CD:~0,1% then it will show "C"

so we can change "set Disk=h" to:

set Disk=%CD:~0,1%


Top

Read and Write a variable to a file

Occasionally I need to write a variable to a text file and read it back using some other batch file. It’s relatively easy to do as these examples show:

Using Echo

Write variable to file   Read text to variable from file

ECHO %fred2% >test.txt

 

SET /P fred=<test.txt
echo %fred%

  • SET fred2=123 sets variable to 123
  • ECHO %fred2% Writes the variable normally to screen
  • >test.txt redirects output to file and not screen
 
  • SET /p : Sets the value of variable to a line of input.
  • fred is the variable
  • < directs a line of text from the file test.txt
  • echo %fred% just a test displays it to screen

Alternative using Set /p

Alternative read and write a variable to a file. Using echo each variable written will have CRLF appended, this may be undesirable, if this is a problem use the following solution it uses Set /P:

SET /P ;variable=[promptString] The /P switch allows you to set the value of a variable to a line of input entered by the user. It displays the specified promptString before reading the line of input. The promptString can be empty or a variable.

We are interested only in the fact a promptString is written to the screen this can be redirected to a file. The variable is never used name it dummy (or whatever you like) a user input is expected to set this dummy variable. An automatic user response can be achieved by piping contents of the nul file to it.

Using the original as an example gives:

1) Write variable to file   2) Read text to variable from file

(set /p dummy=%fred2%) >test.txt <nul

 

SET /P fred=<test.txt
echo %fred%

  • SET fred2=123 sets variable to 123
  • set/p dummy=%fred2% Writes the variable normally to screen
  • >test.txt redirects output to file and not screen
  • <nul provides data from nul file as response (nothing)
 
  • SET /p : Sets the value of variable to a line of input.
  • fred is the variable
  • < directs a line of text from the file test.txt
  • echo %fred% just a test displays it to screen

Using echo I have never been able to set a file to have no content however using set /p its easy:

3) Write nul to file Comments

(set /pset dummy=)set >c:\other\test.txtset <nul

I have shown the file located in some other folder (not local folder) what’s important is (set/p dummy=) this writes nothing to the screen, when redirected creates an empty file

Note: The single pipe “>” creates a new file while a double pipe “>>” appends to an existing file. Combine this with set /p you can create a line of text one variable at a time:

4) Write nul to file Comments

(set /p dummy=Uniform) >test2.txt <nul
(set /p dummy= Server) >>test2.txt <nul

The first line creates a new file named test2.txt and writes Uniform to it. The second line appends to test2.txt “ Server” note the space. The file will contain the following line “Uniform Server”

Set /P is very flexible and worth keeping in your toolbox.

Practical example

I tend to ramble on however I do like working examples take this line SET /P pass=<..\www\mysql_password it can be found on this page Close bat a solution for stopping the MySQL server if the default virtual drive is not used.

Top

Delay

For whatever reason there is no batch file command to produce a delay. It is possible to use a tight loop to simulate a delay at the expense of using one hundred percent processor time. This prevents other programs executing until the loop is complete.

The following produces a delay that is reasonably accurate works fine on XP-Home and does not stall the processor thus allowing other programs to run at the same time. It uses ping and directs output to a nul file.

Delay Example Comments

ping 1.1.1.1 -n NumberOfRetries -w TimeToWaitBetweenTries

NumberOfRetries: Any non zero number
TimeToWaitBetweenTries: Time in milliseconds

ping 1.1.1.1 -n 2 -w 1000

Produces a 2 second delay (Output to screen)

ping 1.1.1.1 -n 2 -w 1000 >> log.txt
#del log.txt

For testing you may wish to log data to a file.
Can delete the log file (No output to screen)

ping 1.1.1.1 -n 2 -w 1000 > nul
ping 127.0.0.1 -n 2 -w 1000 >nul

Produces a 2 second delay (No output to screen)
Output directed to a nul file (file does not exist)

Top

IF Else

IF

General form: IF {Statement} {If statement is TRUE, perform this action}
Note: All on a single line

IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command

NOT Specifies that Windows 2000 / XP should carry out the command only if the condition is false.
ERRORLEVEL number Specifies a true condition if the last program run returned an exit code equal to or greater than the number specified.
string1==string2 Specifies a true condition if the specified text strings match.
EXIST filename Specifies a true condition if the specified filename exists.
command Specifies the command to carry out if the condition is met. Command can be followed by ELSE command which will execute the command after the ELSE keyword if the specified condition is FALSE

Else:
IF {Statement} ({If statement is TRUE, perform this action}) ELSE ({If statement is TALSE, perform this action})

Examples:

IF (%1)==() GOTO END When parameter %1 is empty, the test evaluates to TRUE

if (%first%)==(%second%) goto :next
When parameter %first% and %second% are equaly jump to next

if errorlevel 3 goto :PAUSE
if errorlevel 2 goto :PAUSE
if not errorlevel 1 goto :STARTED

Note: Error levels are processed in descending order. Error level 1 would capture 2 and 3.

Top

SET

SET [variable=[string]]

  • variable Specifies the environment-variable name.
  • string Specifies a series of characters to assign to the variable.

SET /A expression
SET /P variable=[promptString]

The /A switch specifies that the string to the right of the equal sign is a numerical expression that is evaluated.

Example:

Increment a variable

set /a cnt=0
set /a cnt+=1

Top

SUBST command

Uniform Server puts this command to good use, in actual fact the architecture revolves around it. The bottom line it's what makes UniServer portable and quite a nice piece of lateral thinking by the designer.

1) SUBST example: The SUBST command allows you to map any folder (or physical drive) to a drive letter.
SUBST Z: C:\ Maps the C drive to virtual drive Z
SUBST S: C:\test Maps the folder test to virtual drive S
SUBST W: E:\new\uniserver Maps the folder uniserver to virtual drive W
2 ) List all example: To list all virtual drives created open a command prompt.
SUBST Type SUBST with no parameters. This will list all drive letters and their corresponding folder mappings.
3) Delete example: To delete a virtual drive use the /D parameter.
SUBST Z: /D Deletes drive Z
SUBST S: /D Deletes drive S
SUBST W: /D Deletes drive W

You can use a virtual drive like any other drive; any actions performed on the virtual drive in reality are being performed on the mapped folder. Hence if you delete a file or folder on a virtual drive you are deleting a real folder or file on the mapped folder or drive.

Note: Once deleted they are not recoverable from the recycle bin they are permanently deleted.

Top

Registry Manipulation

This section focuses on reading and editing Windows XP registry using REG.EXE which is a native command.

A quick overview of what REGEDIT can do is shown below:

Adding items REGEDIT /S fred.REG The /S switch is optional (skips message dialogs before/after the import) in this example fred is the name of the file to import.
Removing entries [-HKEY_CURRENT_USER\MyTree] To remove an entire "tree" add a minus sign before the tree name.

For example this removes the entire tree "MyTree" from the registry.

  [HKEY_CURRENT_USER\MyTree2]
" ValueToBeRemoved"=-
To remove an individual item from the registry, place the minus sign after the equal sign.

For example this removes the individual value "ValueToBeRemoved" from "MyTree2".

Reading (exporting) REGEDIT /E fred2.REG "HKEY_XXXX\Some Key " The /E switch can be used to read (export) a registry key:

Writes the registry key "HKEY_XXXX\Some Key" and its sub-keys to a file named fred2.REG The resulting text (fred2.REG) file will contain entries in the format "key"="value". Adding and Removing items

Adding and Removing items

Adding and removing registry items requires a temporary file *.REG (note the file extension REG) containing the elements to be added (imported) and or removed. The file is imported into the registry using the following command REGEDIT /s run from a command prompt:

Temporary file

The temporary file *.REG must have the following syntax (format):

REGEDIT4 All registry scripts must start with REGEDIT4 (backwards compatibility)
  This line must be blank
[-HKEY_CURRENT_USER\MyTree] Keys to change (import)
  Optional line between each key (makes it easier to read)
[-HKEY_CURRENT_USER\MyTree] Final key to change (import)
  The last line of a reg file must be blank.

You can also execute a *.reg file by double clicking it (the file extension .reg is associated with regedit).

REG files can also be run from a batch file see next section.

Top

REG Examples

I am sure you are aware editing the registry can be very dangerous because of this deters most people. A bit of confidence building is in order, first lets locate the key we wish to remove by running regedit. (Assumes you have installed the Updater)

Start > click Run > type regedit in the text box and click OK

This opens the edit window, starting from the top left, expand the folder tree by clicking on the plus to the left of these folders:

  • HKEY_CURRENT_USER
  • Software
  • Kana Solution
  • You will see this folder: DynDNS Updater
  • Right click on this folder (DynDNS Updater) and select Copy Key Name
  • (This saves the complete path in the past buffer hence you can past it into a document)
  • Complete path:
  • HKEY_CURRENT_USER\Software\Kana Solution\DynDNS Updater

Click on the folder DynDNS Updater and note the parameters set in the right window. You should see the ini path and version number.

You could use this edit window to delete the registry key. However the above shows how to easily obtain the full path to a known key and paste the result into a batch file this prevents typing errors.

Top

REG Example - 1

This example shows how to read a registry key using a batch file. First create a new folder (name it whatever you like) then create this batch file and save it to your new empty folder.

test1.bat

@ECHO OFF
cls
echo ========= TEST1.BAT READ KEY ==========
echo Creating file fred.reg and reading key
:: Read registry
START /W REGEDIT /E test_result.REG "HKEY_CURRENT_USER\Software\Kana Solution\DynDNS Updater"
pause

Run test1.bat by double clicking on it, when run you will see a new file named test_result.reg. Open this file and you will see something similar to the following:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Kana Solution\DynDNS Updater]
" Version"="3.1.0 (Build 15)"
" IniFile"="G:\\Uniform Server\\dyndns_updater\\DynDNS.ini"

The important line in the above batch file is:

START /W REGEDIT /E test_result.REG "HKEY_CURRENT_USER\Software\Kana Solution\DynDNS Updater"

Breaking it down:

START /W --- Runs the program REGEDIT and the /w instructs the batch file to wait until the program REGEDIT closes before continuing.

REGEDIT /E --- REGEDIT is the program to be run, the /E instructs it to run in export (read) mode.

test_result.REG --- This is the file where the export date will be written, if it does not exist it is created.

"HKEY_CURRENT_USER\Software\Kana Solution\DynDNS Updater" --- This is the key to be exported and must be contained in quotes.

Top

REG Example - 2

This example is a little more interesting it shows how to dynamically create a temporary file using a batch file. This new file will be used for deleting the above registry key. Note: At this stage it will not delete the key.

test2.bat

@ECHO OFF
cls
echo ========= TEST2.BAT Create Temp File ==========
echo Creating a temp file of the correct format
echo File will be named reg_delete.reg

:: Create a temporary REG file
> reg_delete.reg ECHO REGEDIT4
>> reg_delete.reg ECHO.
>> reg_delete.reg ECHO [-HKEY_CURRENT_USER\Software\Kana Solution]
>> reg_delete.reg ECHO.

pause

Run test2.bat by double clicking on it, when run you will see a new file named test_result.reg. Open this file and you will see something similar to the following:

REGEDIT4

[-HKEY_CURRENT_USER\Software\Kana Solution]

The batch file uses > and >> combined with ECHO breaking down the first two lines will explain what they do:

 >reg_delete.reg ECHO REGEDIT4 

The ">" instructs a batch file what follows will be directed to the named file and overwrite it's content. If the file does not exist create it. ECHO Instructs the batch file to output what follows until it reaches end of line. (Writes REGEDIT4 to the file reg_delete.reg)

 >> reg_delete.reg ECHO.

The ">>" instructs a batch file what follows will be appended to the named file.
ECHO. Instructs the batch file to output a blank line. (Writes a blank line to the end of file reg_delete.reg)

ECHO with no dot. Instructs the batch file to output what follows until it reaches end of line. (Writes another line to the end of a file).

That covers every thing we need to zap that registry key.

Top

REG Example - 3

To remove the registry key combine example 1 and 2 as follows:

test3.bat

@ECHO OFF
cls
echo ========= TEST3.BAT Zap registry key ==========
echo Creating a temp file of the correct format
echo File will be named reg_delete.reg

:: Create a temporary REG file
> reg_delete.reg ECHO REGEDIT4
>> reg_delete.reg ECHO.
>> reg_delete.reg ECHO [-HKEY_CURRENT_USER\Software\Kana Solution]
>> reg_delete.reg ECHO.

Import file to registry

echo Zapping Key
START /W REGEDIT /S reg_delete.reg

echo Finished

pause

The line START /W REGEDIT /S reg_delete.reg runs REGEDIT in silent mode, and imports the file removing the key. Note: Delete file test_result.REG now run test1.bat the file will no longer be created because there is nothing to export. It will only be re-created if there is data to write.

Essentially that is the solution to the portability problem; with a few minor changes we can integrate that into our design.

Top

REG Final

Example 3 leaves its own dross behind in the form of that temporary file, easily resolved by deleting it. For user feedback most of my test files contain echo statements only required when using the pause command. The cleaned file is shown below, save this to folder dyndns_updater:

remove_key.bat
@ECHO OFF
cls
:: Removes Updater registry key. Tested on XP home

:: Create a temporary REG file named reg_delete.reg
:: Write correctly formatted data to file
> reg_delete.reg ECHO REGEDIT4
>> reg_delete.reg ECHO.
>> reg_delete.reg ECHO [-HKEY_CURRENT_USER\Software\Kana Solution]
>> reg_delete.reg ECHO.

:: Import file to registry removes registry Key
START /W REGEDIT /S reg_delete.reg

:: Clean up own dross
del reg_delete.reg

This batch file will be run from "Stop.bat" file which needs modifying as follows:

Open Stop.bat and add the line shown in bold I have show only part of this file.

Stop.bat
@echo off
udrive\home\admin\program\pskill.exe Apache.exe c
udrive\home\admin\program\pskill.exe DynDNS.exe c
call dyndns_updater\remove_key.bat

You can run the file by double clicking it alernatively run it from within another batch file by adding the line call remove_key.bat

Top


Ric