Batch files: Snippets 1: Difference between revisions
mNo edit summary |
mNo edit summary |
||
Line 1: | Line 1: | ||
{{Uc nav batch files}} | |||
{ | |||
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! | 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! | ||
Line 697: | Line 685: | ||
{| | {| | ||
| [[Image:uc_small_logo.gif]] || [[User:Ric|Ric]] | | [[Image:uc_small_logo.gif]] ||[[User:Ric|Ric]] | ||
|} | |} | ||
[[Category: UniCenter]] | [[Category: UniCenter]] |
Latest revision as of 22:48, 2 August 2008
Batch Files: Snippets 1 | First Free Drive |
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 % |
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.
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.
Current drive letter 1
To pick up the current drive letter (where the batch file resides) use:
Note: Drive includes colon e.g W: |
|
Note: Drive letter only e.g W |
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%
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 | |
|
|
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 | |
|
|
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 |
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.
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 |
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 |
For testing you may wish to log data to a file. |
ping 1.1.1.1 -n 2 -w 1000 > nul |
Produces a 2 second delay (No output to screen) |
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.
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
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.
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.
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.
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 |
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] |
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.
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 :: Create a temporary REG file 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 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.
REG Example - 3
To remove the registry key combine example 1 and 2 as follows:
test3.bat |
---|
@ECHO OFF :: Create a temporary REG file
echo Zapping Key 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.
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
Ric |