Cay S. Horstmann
In the first lab, you learned the
basics of using the Windows command
shell. In this lab
you will learn how to automate shell commands. You will create batch
files
consisting
of sequences of commands that can be executed again and
again. First, however, we will review the basic shell commands.
Exercise
1 |
Open a command shell window. Describe what you did to open it. |
Exercise
2 |
In the command shell window,
change to your personal directory. (If necessary, create it.) What
commands did you issue? |
Exercise
3 |
Inside your personal directory,
create a subdirectory named advanced.
What command did you issue? |
jar -xf bank.zipextracts the files from the file bank.zip into the current directory. (The xf denotes extraction from a file.)
Exercise
4 |
Unzip the file bank.zip now. How many files
were stored inside it? (Hint: dir) |
![]() |
NOTE: If you get a "command not found" error message when
executing the jar
command, then you need to specify the full path name of the jar.exe program, such as c:\j2sdk1.4.2\bin\jar.exe. You
may need to spend some time looking for the jar.exe file, or ask a lab
assistant. If you do this exercise on your own computer, make sure that
the Java SDK is installed. You can download it from http://java.sun.com/j2se. |
When you submit your homework by email, your instructor will
probably
ask you to zip up all homework files. A beginner would use a
program such as WinZip for this
task. You know the drill. Click on the WinZip icon. Click, click,
click, until you have added each file. Click, click, click, type
the zip file name, click, click, and you are done. Did you need to make
a last-minute
change to a file? Do it all
over again. And again.
You can do better than that. The command
jar -cf homework.zip *.java
makes a zip file called homework.zip
that contains all Java files in the current directory. (The cf option denotes compression to a file.)
Maybe you also need to include some other files (such as Javadoc documentation and UML diagrams). Then the command gets longer.
jar -cvf homework.zip *.java *.html *.jpg
(The v option produces
verbose output,
listing the actions that the jar
command takes.)
Rather than typing the command every time, you can place it into a batch file, and run the batch file as a single command. We will start with a simple version of such a batch file.
Start the Notepad program. Type in the following text:
@echo off
rem Zip up source, HTML, images
jar -cvf homework.zip *.java *.html *.jpg
Then use the File ->
Save as
menu option to save the file as c:\yourname\advanced\zipup.bat.
![]() |
NOTE: Depending on the Windows configuration, the Notepad
program may add a .txt
extension to the file name, that is, zipup.bat.txt. (This evil and stupid
behavior may be hard to spot unless you changed the Windows Explorer's
evil and stupid default of "hiding known file extensions". You learned
how to make that change in lab #1.) The remedy is to surround the file
name in double quotes: "zipup.bat". |
zipupIn general, you execute the commands in a batch file by typing the name of the file (without the extension .bat).
Exercise
5 |
Run the zipup batch file now, in the c:\yourname\advanced
directory. Before running the batch file, make sure that the directory
contains a few Java files (from the preceding exercise). What is the
result of running the batch file? |
The first two commands of
the start batch file are new commands. @echo off
suppresses the
display of each command on the screen as it is executed. A line
starting
with rem contains comments that are ignored by DOS.
Exercise
6 |
Comment out the line @echo off (by prefixing it with rem). Run the batch file. What is the difference? |
Your instructor may ask you to run the Javadoc program to extract
document comments before you submit your homework. The command is
javadoc *.java
Exercise
7 |
Enhance the zipup.bat file to
automatically execute the javadoc
program. Call the file zipup2.bat.
What is the contents of the file now? |
As you make more changes to the file, keep changing the name (zipup2, zipup3, etc.) Then you
can submit the various versions for grading.
Suppose you sometimes want to zip up your homework to hw1.zip, then to hw2.zip, or even to hw1_1728.zip. This can be easily done by modifying zipup.bat.
Change the filename homework.zip
to %1.zip:
jar -cvf %1.zip *.java *.html *.jpg
When executing the batch file, you now need to supply the name of
the zip file (without the .zip
extension which is appended in the batch file). For example,
zipup3 hw1
Then the %1 is
replaced by hw1. %1 is the first argument of the
batch
file, %2 is the second,
and so on.
Exercise
8 |
How do you run the batch file to
save your homework to hw1_1728.zip? |
Exercise
9 |
Type zipup3 without an argument.
What happens? |
Let's modify the batch file
to give an error message if no command line argument is specified.
Add the following lines to the batch file and name it zipup4.bat.
@echo off
if "%1" == "" goto error
rem Zip up source, HTML, images
jar -cvf %1.zip *.java *.html *.jpg
goto end
:error
echo Usage: zipup4 filename
Exercise
10 |
Now type zipup4 without an argument.
What happens? |
The if "a"
== "b"
command tests whether the strings a
and b are equal. The goto
command goes to a label. Each
label
starts with a colon (:).
The echo command displays
a
message
on the screen.
Exercise
11 |
Create a directory c:\yourname\hw1. Change to that
directory. Copy all Java files (but not the batch file) from the c:\yourname\advanced directory,
so that you can pretend that you just completed a homework assignment.
What shell commands did you use? |
Exercise
12 |
Now type zipup4 hw1. What happens? |
Exercise
13 |
Type the command set. Look for the definition of
the PATH variable. What
result do you get? |
c:\windows;c:\windows\system32If you work in a computer lab, the lab administrator probably has added the directory for the Java commands (c:\j2sdk1.4.2\bin or something similar).
![]() |
NOTE: Depending on your version of Windows, the environment
variable may be listed as Path,
not PATH. That's ok--in
Windows, environment variables are not case-sensitive. However, it is
considered good style to use uppercase letters for environment
variables. |
@echo offBe very careful with the spacing. There must be no spaces around the symbols = ; %. Only set and PATH are separated by a space.
set PATH=c:\yourname\advanced;%PATH%
echo The PATH is now %PATH%
set PATH=...sets the PATH environment variable to the expression on the right hand side.
Exercise
14 |
Execute the myenv.bat batch file. What
result do you get? |
![]() |
NOTE: In Windows XP, you can also execute the command set PATH=...;%PATH% directly on
the command line. However, in older versions of Windows, the %PATH% expression works only
inside a batch file. |
Exercise
15 |
Make sure that you are currently
in the c:\yourname\hw1
directory. Now type zipup4
hw1. What happens?
Why does the zipup command
work now? |
java com.puppycrawl.tools.checkstyle.Main -c sjsu.xml BankAccount.javaHere, com.puppycrawl.tools.checkstyle.Main is the Main class in the com.puppycrawl.tools.checkstyle package. That class has a method public static void main(String[] args) that kicks off the CheckStyle program.
Exercise
16 |
Change to the c:\yourname\advanced directory.
Download the file checkstyle-all-3.1.jar
into that directory. Also download the file sjsu.xml and save it in the
same directory. That file contains rules for the SJSU CS department
style guide. Now type java com.puppycrawl.tools.checkstyle.Main -c sjsu.xml BankAccount.javaWhat happens? |
set CLASSPATH=.;c:\yourname\advanced\checkstyle-all-3.1.jar
Note that the CLASSPATH
contains the current directory (.).
Exercise
17 |
Execute the command for setting
the CLASSPATH. Now type java com.puppycrawl.tools.checkstyle.Main -c sjsu.xml BankAccount.javaWhat happens? Why does the command now work? |
Exercise
18 |
Write a batch file check.bat so that you can check
the style of any Java file. For example, check BankAccount.javaIn your batch file, you need to specify the full path name for the jar file and the sjsu.xml file. Otherwise, your batch file won't work when it is called from another directory. Because the same directory name occurs twice, use an environment variable: SET CHECKSTYLEHOME=c:\yourname\advancedWhat is the contents of your batch file? |
![]() |
NOTE: You can avoid the use of the CLASSPATH environment variable
by using the -classpath
option for the javac and java commands. For example, java -classpath c:\yourname\advanced\checkstyle-all-3.1.jarOf course, such a long command only makes sense inside a batch file. |
![]() |
NOTE: Occasionally, it does make sense to make permanent
additions to the PATH.
For example, after downloading the Java SDK, you should add the
directory for the Java commands to the PATH. In Windows XP, open the
control panel. Make sure it is in classic mode. Click the System icon, then on the Advanced tab, then on the Environment Variables button. Edit
the PATH variable in the System Variables section. The same
method works for Windows NT and Windows 2000. |
![]() |
NOTE: For Windows 95, 98, and
ME, you use a completely different (and more sensible) approach to
change the PATH
environment variable. Edit the file c:\autoexec.bat (or create it
if it doesn't already exist). Then place the set PATH=...;%PATH% command
inside that batch file. It is executed whenever your computer boots up.
|
![]() |
NOTE: Globally setting the CLASSPATH variable (in the
control panel or autoexec.bat)
will only bring you grief in the long run. Don't do it. Set CLASSPATH in a project batch
file, or use the -classpath
option. |
![]() |
NOTE: If you use Windows 95/98/ME, you may run out of
"environment space" if you set too many environment variables.
The remedy: In the shell window, click on the Properties button, then pick the Memory tab and set the Initial Environment to the maximum
value (4096). |
command > file
sends the output of a command to a file.
Exercise
19 |
Execute the commanddir c:\windows > out.txtThen look inside the out.txt file. What do you see? What is the last line in the file? |
grade hw1_1728 BankAccountTest
Exercise
20 |
What are the commands to unzip
the file hw1_1728.zip,
compile the Java source, run the BankAccountTest
program, and capture the output in the file hw1_1728.txt? Hint: Use
redirection: java ... > ... |
Exercise
21 |
Now write the grade.bat file. Simply take the
results from the preceding exercise and replace hw1_1728 with %1 and BankAccountTest with %2. What is the contents
of grade.bat? |
Exercise
22 |
Make sure that both grade.bat and bank.zip
are in the c:\yourname\advanced
directory. Then run grade bank BankAccountTestWhat output file was created? What is the contents of that file? |
java -jar checkstyle-all-3.1.jar -c sjsu.xml *.java > homework.txtNote the echo command. It produces a line of output, ===Program Run===. That line is appended to the homework.txt file.
javac *.java
echo ===Program Run=== >> homework.txt
java BankAccountTest >> homework.txt
Exercise
23 |
Add this enhancement to the grade.bat file and call the
result grade2.bat. As
before, make
sure the file can be executed from any directory. (Note that we use a
different method for invoking CheckStyle, with the -jar option. This option does
not require you to set the class path.) What is the contents of grade2.bat now? |
Finally, let us capture the compiler output in the homework report
as well. Unfortunately, now we have a problem. Compiler errors are
reported to the standard error
stream, not the standard output
stream. The > and >> commands only
redirect the standard output stream. The remedy is to use the 2> operator which redirects
the standard error stream. (For historical reason, that stream is also
known as stream #2.)
javac *.java 2> homework.txt
There is also a 2>>
operator to append the standard error stream output.
![]() |
NOTE: The 2>
operator does not exist in Windows 95/98/ME. For these versions of
Windows, compile the following Java class:import java.io.*; Then execute the following command: java Errout javac MyProg.java > homework.txt |
You can also supply the
input
to programs in a file rather than keying it in. This is useful when
supplying program input for testing. The < operator redirects console
input to a file. That is, whenever the program wants to read input, it
grabs it from the file, not the keyboard.
Download and unzip the interest.zip file. Open the
SavingsAccountTest program
with the Notepad program and have a glance at it.
The test
program asks the user to supply several values.
Exercise
24 |
Compile and run the SavingsAccountTest program.
What balance do you get after 10 years with an initial deposit of
$10,000 at 5% interest? |
As a grader, you would not want to type in the same input values
over and over. Therefore, let us place the program inputs into a file input1.txt.
Exercise
25 |
Create an input.txt file with
three lines, one for each program input. Run the commandjava SavingsAccountTest < input1.txtNote that you no longer provide any keyboard input. What output do you get? |
Input redirection only works with console
input, not with input into dialog boxes. For that reason, the SavingsAccountTest program uses
the BufferedReader class,
not the JOptionPane class.
Some commands are
specifically
designed to work with input from the keyboard (thus allowing redirected
input). The sort program is an example.
Exercise
26 |
Try the following:
dir c:\windows > out.txtWhat is the result? |
The sort program reads from standard input (that is, the keyboard or a redirected file). It is possible (although not very useful) to have sort sort some lines of keyboard input.
Exercise
27 |
Type sort and
then the
following lines. MaryHit Enter after each line. When you are done, hit Ctrl-Z and Enter. Ctrl-Z is a special key that tells the shell to stop sending keyboard input to the program. What is the result? |
As you just saw, sorting a directory listing can be achieved in two steps. First capture the listing in a file (dir > out.txt), then sort the captured output (sort < out.txt). Because this combination is so frequent, there is a shortcut for it, called a pipe.
dir | sort
This pipe, written with a vertical bar, runs dir, stores its output in a temporary file, then runs sort and redirects its input from that temporary file, and then automatically deletes the temporary file.
Another useful program that reads from standard input is more. The more program stops every screen full and waits for you to hit a key before continuing.
Exercise
28 |
Type the commanddir c:\windows | moreWhat happens? |
You can pipe any sequence of commands together.
Exercise
29 |
Type the commanddir c:\windows | sort | moreWhat happens? |
Let's look at the grade.bat
file again. Suppose a student submitted a file that doesn't even
compile. Then we should abort the batch file after the call to javac, without trying to
execute the program.
Every program returns an integer value, called the error level, to the operating
system. By convention, a program returns the value 0 when it is
successful and a non-zero value to indicate some kind
of error. In your own Java programs, you can set the error level by
calling
System.exit(level);The Java compiler sets the error level to 0 when a program compiled successfully, and to a non-zero value otherwise.
You can test the error level of a program in a batch file.
javac *.java
if errorlevel 1 goto error
...
goto end
:error
echo Program didn't compile > %1.txt
:end
Exercise
30 |
Add this enhancement to your
grading batch file and call the result grade3.bat. Test it by
introducing an error in the BankAccount.java
file: Change class to lass. Then create a new zip
file bad.zip that
contains the file with the error.
|
The if errorlevel n
command tests whether the error level is >= n. Thus, if you have a
program that returns 1 for a mild error and 2 for a fatal error, then
you want to first carry out a check if errorlevel 2, then if errorlevel 1.
You know how to make simple branches in batch files with commands
such as
if "%1" == "" ...
if errorlevel 1 ...
if exist input1.txt ...
As you can see, you can do simple programming in batch files. For
more advanced programming, you need the for construct.
There are two
separate versions of for:
for %f in (*.java) do javac %f
for %d in (A,C,D) do dir %d:
The first for loop
lets the variable %f run
through all files that match the pattern *.java. The second for loop lets the variable %d run through the three
choices A, C, D.
Variables in a for
loop must always start with a %
sign. However, inside a batch file, you must use two% signs, such as
rem this is inside a batch file
for %%f in (*.java) do javac %%f
Now let us put this technique to work in our grading batch file. We
want to feed
all input files of the form input*.txt
to the program to be graded. That way, the grader can prepare an
arbitrary number of files input1.txt,
input2.txt, etc. Ideally,
we would like to issue the command
for %%f in (input*.txt) do java %2 < %%f >> %1.txt
Sadly, this command does not work in all versions of Windows. In
some Windows versions, you cannot mix the redirection operators with
the for loop.
![]() |
NOTE: Incompatibilities between Windows versions are a
vexing problem for authors of sophisticated batch files. Most shell
users eventually give up in disgust and migrate to another shell such
as the bash shell. In Windows, install the excellent Cygwin package to get a bash shell
and a wealth of powerful command-line tools with well-defined behavior.
|
In this situation, you can solve the compatibility problem with
trick. Write a second batch file gradehelper.bat
that contains as its single command the body of the for loop.
rem this is gradehelper.bat
rem %1 is the name of the output file (without extension)
rem %2 is the name of the program file (without extension)
rem %3 is the name of the input file (with extension)
java %2 < %3 >> %1.txt
Then the original batch
file can call gradehelper:
rem this is grade4.bat
rem %1 is the name of the output file (without extension)
rem %2 is the name of the program file (without extension)
. . .
for %%f in (input*.txt) do call gradehelper %1 %2 %%f
. . .
(You use of call
command to call a batch file from inside another batch file.)
Exercise
31 |
Add this enhancement to your
grading batch file. Call the result grade4.bat. Test it by
producing two files input1.txt
and input2.txt with
different inputs for the SavingsAccountTest
program.
|
echo gradehelper.bat is called with parameters %1 %2 %3or
for %%f in (input*.txt) do echo Need to call gradehelper %1 %2 %%f
Exercise
32 |
The grade4.bat file grades a single
homework submission. Suppose you are the grader, and you have to grade
dozens of submissions, each of which has the form hw1_xyzw.zip, where xyzw is a four-digit number.
Write a file gradeall.bat
that grades all files and produces a combined report for all of them. Hints:
|
Hopefully, these exercises have given you a feel for the power of
automation. While it is undeniably challenging to automate a task for
the first time, the effort is repaid handsomely. It is fun to
watch the computer do the same boring tasks over and over, particularly
if you consider how much time it would have taken you to do it by hand.
In your programming and testing process, you carry out lots of
repetitive steps. Automate them, and you will become more productive.
You will also find that you would never attempt certain tasks without
automation. For example, consider the task of testing your programs.
Whenever you change a program, you should really test it again with a
bunch of inputs. Do you do that? Probably not. What could be more
tedious than typing in the same inputs over and over again? You now
know that you can automate that task. Put a bunch of test inputs into
files and write a batch file that automatically feeds them into your
program. Test automation leads to higher quality programs.
For those reasons, all professional programmers are serious about
automating their build and test processes. You have just learned how to
use the command shell for basic automation tasks.