Win32
Shell Scripting
Scripting is a way by which one can
alleviate this necessity by automating these command sequences in order to make
ones life at the shell easier and more productive.
The
Environment
The environment is an area of memory associated with the
command processor that provides upto 32KB of space for storing variables, the
variables contain information about the operating environment that is used by
the operating system and other programs in various ways, typically to inform a
program of the location of a certain piece of information it requires. A few
examples follow:
ComSpec, specifies the location of the command interpreter.
PATH, specifies the locations to search for commands typed
at the command line.
Prompt, specifies how the command prompt should appear to
the user.
AGE, a user-defined variable for indicating the age of
something.
TEMP, specifies the directories where temporary files
should be placed.
Sometimes it is necessary to modify certain environment
variables, for instance, we may have installed a new program in a directory
such as C:\tools\chipper\, and its executable files may be stored in C:\tools\chipper\bin\.
We may desire to execute this program from the command line but find that we
get an error saying something like:
'chipper' is not recognized as an internal or external
command, operable program or batch file.
|
Because we had not updated the PATH to point to the
location of the binary files for this program.
Altering environment variables will depend on what version
of Windows you are using, see Configuring A Windows Working Environment.
Batch
Programming
A batch file is a plain ASCII text file with the file
extension .bat, it is interpreted by the command processor, usually command.com
or cmd.exe. Batch files are used to automate repetitive command sequences in
the command shell environment.
In the context of batch programming, the
environment is exploited for it's ability to store text strings within
definable variables known as environment variables as illustrated in the above
example, these variables can be used in batch files in much the same way as you
would use variables in other programming languages albeit with less freedom.
The language used in batch files is usually referred to as a scripting language
but it is in-fact Turing-complete hence is actually a programming language
Auxiliary
files for extended batch programming
Unfortunately, due to reasons unknown, many useful tools
for batch programming have been omitted in recent versions of Windows and are only
available from within costly 'resource kits' that one has to purchase for
seemingly extortionate sums of money. However, there are free alternatives to
some of these tools and/or hacks/kludges to circumvent their necessity.
1.1.
OldDos.exe
This is a self-extracting archive containing some of the
files that were distributed with versions of Windows prior-to and including Windows
95, programs such as qbasic.
1.2.
NT Resource Kit
This is a subset of the tools found in the full Windows NT
Resource Kit. Only available for Windows 2000/NT/XP users.
1.3. CHOICE.EXE
CHOICE.EXE is a batch command which allows the requisition
of a choice from a basic set of choices presented to the user.
Batch Basics
Command
Redirection and Pipelines
If you want to get help on a command in Windows, the usual
way is to postfix the command with a space and then /?.
By default a normal command accepts input from standard
input, which we abbreviate to stdin, standard input is the command line in the
form of arguments passed to the command. By default a normal command directs
its output to standard output, which we abbreviate to stdout, standard output
is usually the console display. For some commands this may be the desired
action but other times we may wish to get our input for a command from
somewhere other than stdin and direct our output to somewhere other than
stdout. This is done by redirection:
Pipelines are another form of redirection that are used to
chain commands so that powerful composite commands can be constructed, the pipe
symbol '|' takes the stdout from the command preceding it and redirects it to
the command following it:
Variables
1.2.2.1. Variables
New variables can be instantiated like this:
The name must only be made up of alphabetic characters,
numeric characters and underscores, it cannot begin with a numeric character.
You cannot use keywords like for as variable names.
Variables are referenced like this: %name%, here is an
example:
This would echo "Hello There!" to the console
display, here is another example:
Would echo "one two three" to the screen. If you
would like to echo the '%' character, escape it with another '%' like this
'%%'. You can echo to another file to create a new batch file if you like:
This would cause "set msg=Hello World!" to be
echoed and redirected to the file hello.bat, "echo %msg%" is then
echoed and redirected to the file hello.bat but this time appended to the end.
Notice the double '%' in the program-listing so that the '%' character is
echoed and not interpreted as being the opening of a variable name. The final
line executes hello.bat causing it output "Hello World!".
Command
Line Arguments
Command line arguments are treated as special variables
within the batch script, the reason I am calling them variables is because they
can be changed with the shift command. The command line arguments are
enumerated in the following manner %0, %1, %2, %3, %4, %5, %6, %7, %8 and %9.
%0 is special in that it corresponds to the name of the batch file itself. %1
is the first argument, %2 is the second argument and so on. To reference after
the ninth argument you must use the shift command to shift the arguments 1
variable to the left so that $2 becomes $1, $1 becomes $0 and so on, $0 gets
scrapped because it has nowhere to go, this can be useful to process all the
arguments using a loop, using one variable to reference the first argument and
shifting until you have exhausted the arguments list.
Control
Contructs
The flow of control within batch scripts is essentially
controlled via the if construct.
If
This construct takes the following three generic form, the
parts enclosed within '[' and ']' are optional:
When a Windows command exits it exits with what is known as
an error level, this indicates to anyone who wants to know the degree of
success the command had in performing whatever task it was supposed to do,
usually when a command executes without error it terminates with an exit status
of zero. An exit status of some other value would indicate that some error had
occurred, the details of which would be specific to the command. This is what
the error-level if is for.
What this example does is compare the first command line
argument with the strings "1", "2" and "3" using
== which compares two strings for equality, if any of them match it prints out
the corresponding message. If no argument is provided it prints out the final
case. If you want to include more than one command, enclose it within braces:
Deletes hello.bat if it exists and prints acknowledgments
For
The syntax of the for command is:
In this example first of all we check to see if the file bigtxt.txt
exists, if it does we rename it to bigtxt so that it is not included within the
scope of the next line. The second line says that for every %%f in (*.txt),
which is every *.txt file in the current directory, we should perform the
command type on the files (which prints the file to stdout) and then append
these to the file bigtxt. The third line simply renames the file bigtxt to bigtxt.txt.
A more useful option of the FOR construct is to use the
option /L which turns in to like a numeric mode whereby the following syntax
applies:
Here is an example:
Which will simply, echo all the numbers in between zero and
100 inclusive, incrementing by 2 each time. If you want to include more than
one statement, use brackets after the DO part:
To echo some lines above and below each number.
Loops
The batch language is so brain dead one has to employ
ad-hoccery to get anything useful done, as an example I will illustrate how to
create a simple counter known as a bang counter:
This takes a string of bangs, e.g "!!!", as an
argument and then echos "Bang!" for each bang in the string. The loop
compares the string of bangs to the string i which is set up and loops while
the two strings are not equal, on each loop iteration a bang is added to i
hence the loop will iterate for the number of bangs in the argument string. One
could use this to control the number of times some action was executed. If this
is ran with no arguments the program loops forever because the bangs will never
match.
Simple
Examples
Creating
Aliases
If you always use the same options to a command or would
like to create an alias for a command with a certain set of options, why not
use a batch file to do so, simply create the batch file and place it somewhere
in your path. Make sure that you do not create a batch file with the same name
as an actual command unless you really want to override the command if the batch
file comes earlier on in the PATH. A few examples are shown below:
Example
batch file
The example below illustrates some of the features of batch
programming.
Example 1. Batch file - Concatenate
and zip Example
BatchMaker
example - Unix for Windows (sort of)
I was fed up of accidentally typing ls instead of dir at
the DOS prompt to get a directory listing so I started making some batch files
to map the DOS commands like, move, dir, copy etc. to their Unix equivalents.
For example, here is the mapping for copy to cp.bat:
Which just see's if there is a command line argument
present, if there is not, it prints the usage instructions for the command,
otherwise it executes the command with the maximum number of command line
arguments (9) (just in case). Most of the mappings I wanted to do had this
similar format, only varying in the number of required arguments, this is the
main drawback. For instance ls (dir) takes no arguments so you would not want
to print the usage instructions every time somebody tried to get a directory
listing (the person would not even get their directory listing). What I could
have done was use some kind of contrived kludge of a counter, a bang counter or
something and let the person specify the number of command line arguments on
the command line but I wasn't prepared to waste my time doing so when this
behaviour suited the majority of commands I had to match. OK, I might take a
look at it when I have nothing better to
do... like never ;) This got tedious after a while so I thought it would
be a good idea to make a command to do the mappings for me.
All I had to do to create a batch file that generated this
template was make it echo that template to another file, changing the words
"copy" to whatever the command is and do various other things, here
it is:
When referring to echoing, this will occur to stdout but
the command is used by redirecting the output to a file so what is being echoed
will end up in another batch file. This means the things being echoed are batch
commands. The batch file first checks that it's own command line arguments are
present, if they are not it echos it's command usage. If the command line args are
present, it first echoes:
Because this will be present at the top of all of the batch
files created. It then enters this loop:
Which starts at 1 and iterates by 1until %%i exceeds the
number specified as the second command line argument, so if 1 is specified as
the second argument the body of the loop will be executed once, echoing:
"%%%%i" echos % followed by the value of %%i, the
loop counter. So this loop creates the checks for the command line arguments
that the command being mapped should have. If zero is specified as the second
command line argument, the loop is never executed which is the desired action
since a command with zero arguments needs no argument checking.
Echoes
So that the command will then be executed (in the generated
file) with the maximum possible number of arguments, this is so that when the
command is executed, any redirection and args etc. will be executed too,
otherwise the command would not do anything.
The batch then checks if the number of required arguments
for the command being mapped was zero, if it was then there is no need to echo
the rest of the stuff because a command that needs zero arguments should
generate a file like this:
If the required arguments for the command being mapped is
not zero then the rest of the stuff is echoed, the rest of the stuff just
ensures that if the mapped command is ran with not enough arguments, that
command's usage instructions will be printed by calling the generic DOS help
function of the command with the /? switch. The last line skips the usage
instructions of map.bat so that the batch terminates.
An example usage will clarify, the contents of mv.bat after
executing
are:
So of course you can redirect the batch file to somewhere
in your path or whatever. Here is another quick batch file that generates some
aliases and puts them in a directory of your choice:
Notice that the keyword call is used to call the map, this
is necessary so that after map has finished, program control will return to the
next statement in this batch file. If call had not been used then only the
first statement would have executed because batch would have terminated
after map had.
|