Alright, so I had this friend who didn't have a java compiler, and the internet was shaky, so she didn't want to go for the install. So she asks me if I can simply compile for her, and tell her the error messages. Simple enough! (obviously a bit tedious for her debugging, but hey)
I started by manually typing
>>javac Yosi.java
and just reading out the first error message. Not very efficient.
Next step, I manually typed
>>javac Yosi.java > log.txt
but that just output nothing to log.txt and everything to the console.
So, search engine, and
>>javac Yosi.java > log.txt 2>&1
works like a charm. I don't know exactly what the 2>&1 does, But according to this, it has at least something to do with having two output streams? Anyway.
Then each time I did this, I had to delete the Yosi.java file before I downloaded it again (from my friend), to avoid the Yosi (1).java filenaming.. so I thought, why not put this in a batch script, that would do the compiling and then deleting the file? Simple enough. So my first file just looked like this
#runyosi.bat javac Yosi.java > log.txt 2>&1 rm Yosi.java
and worked like a charm. Soon enough, I got some error messages relating to the Yosi.java not existing (when running the script without the file present), so naturally, I updated the script to account for this
#runyosi.bat if exist Yosi.java ( javac Yosi.java > log.txt 2>&1 rm Yosi.java )Great! Indeed. Then soon enough, I got a file with a new name, Rugl.java, so instead of just changing the Yosi.java in my .bat file, I decided to add another if clause. (had to rename the log file, to account for being able to compile them both at the same time)
#runyosi.bat if exist Yosi.java ( javac Yosi.java > log.txt 2>&1 ) if exist Rugl.java ( javac Rugl.java > log2.txt 2>&1 rm Rugl.java )Now, quickly I realized, this could be generalized! And of course (all of this takes a lot longer than simply doing everything manually, but that's just because I have to search for every other thing) that's what I set out to do.
I don't remember my steps exactly, but I had to search for many many things, here is the final file, I'll explain it a bit then.
#runyosi.bat @echo off setlocal enabledelayedexpansion echo starting .java compilation check.. set list=Yosi.java Rugl.java View.java echo going to test file list: %list% for %%x in (%list%) do ( echo checking file %%x .. if exist %%x ( echo compiling file %%x .. set name=%%~nx javac %%x > log!name!.txt 2>&1 echo removing file %%x .. rm %%x echo file %%x removed ) )
The @echo off command doesn't turn off the stuff I put in echo commands as you might think, but the automatic echoing of commands, that is, for example, without the @echo off, this code would run like this
#test.bat mkdir yeah rm Foo.java >>test >>mkdir yeah >>rm Foo.java
that is, I run the test.bat by typing test, and then it echoes what it's doing, similar to if I had typed it myself.
I'll get into the setlocal... later. I added a bunch of simple print status commands like echo starting .java compilation check.. which just print exactly what you'd think.
set list=Yosi.java Rugl.java View.java
for %%x in (%list%) do ( code )I loop over each element in the list variable and execute the code each time on the element x.
set name=%%~nx javac %%x > log!name!.txt 2>&1
Now things are getting more interesting, alright. So I wanted to be able to output something like "logYosi.txt" and "logRugl.txt" depending on the file name. I started by doing only
javac %%x > log%%x.txt 2>&1
but as you can see, this gives us e.g. logYosi.java.txt. Not quite what we want. Then I set out to find how to eliminate the .java. I figured something like a substring should work, leading me to do something like
javac %%x > log%%x:~0,-5.txt 2>&1
which has the -5 to omit the last 5 letters (the .java). However, I wasn't sure that would work, since the syntax examples had the notation like this
%var:~start,end%. And yes, it indeed did not work. So then I thought of making a variable like thus
set name=%%x javac %%x > log%name:~0,-5%.txt 2>&1all done? Not quite. In fact, I thought this worked for some time, because it did output the correct filename when checking the FIRST file in the list. It was not until I tried the second file, realizing then it still named the log file "logYosi.txt". This is because using the set name as is, simply sets it once and then doesn't change it. So google away! And of course, a solution was found! That's where the
setlocal enabledelayedexpansion
set name=%%~nx
Then nothing left but rm %%x where rm stands for remove. I think you can also use del, but I remembered rm worked (rm like in linux).
So there you have it! A simple batch script that compiles a predefined set of java files and outputs compile errors to a log and subsequently deletes the .java files.
Logging from javac to a file: http://stackoverflow.com/questions/317733/trying-to-capture-javac-output-in-bash-shell
Batch .bat windows script shell if syntax: http://www.robvanderwoude.com/ntif.php
Creating lists in batch (and for loop syntax): http://stackoverflow.com/questions/17605767/create-list-or-arrays-in-windows-batch
Comments in batch scripts: http://www.robvanderwoude.com/comments.php (none of those are in the script right now, but I used them in development of the script, even successfully within the for block)
Substring: http://ss64.com/nt/syntax-substring.html
Temp variable in for loop: http://stackoverflow.com/questions/5615206/windows-batch-files-setting-variable-in-for-loop