Making scripts readable

Ok, I’ve been guilty of this in the past, and so I’m going to show you how to avoid my mistakes. First off, I’m going to use VBScript for my example, so please don’t think that you can copy and paste this stuff into any script, you’ll have to figure out what the character(s) is (are) to define a comment in whatever scripting language you are using (incidentally this is always the first thing I learn when studying a new scripting language).

The intent of this post is not for my code to be reviewed (I intentionally selected an old script, so I am aware that there are some things that could be, let’s say adjusted, to make this script better). The intent is to show three things:

  1. Using a text editor that provides syntax highlighting is probably the one thing that you can do to make scripting noticeably easier from the very first second.
  2. Indenting your code makes it WAY easier to read.
  3. Commenting helps A LOT.

So let’s begin with the code, as I found it in my script library:

'SCRIPT........:  defragXP.vbs
'DATE..........:  09/06/2005
'AUTHOR........:  Joe Glessner
'DESCRIPTION...:  Defragments non removable volumes in XP using defrag.exe Logs results
'to the Application Event log on the local machine.
Const DriveTypeRemovable = 1
Const DriveTypeFixed = 2
Const DriveTypeNetwork = 3
Const DriveTypeCDROM = 4
Const DriveTypeRAMDisk = 5
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set Drives = objFSO.Drives
For Each Drive In Drives
If Drive.DriveType = 2 Then
RunDfrg Drive
logEVT("defragXP..:  Drive " & Drive & " defragmented.")
End If
Next
Function RunDfrg(DriveString)
Set WshShell = WScript.CreateObject("WScript.Shell")
RunString = "%comspec% /c echo " & WeekDayName(WeekDay(Now), True) &_
" " & Now & " " & "Results for drive " & DriveString
Return = WshShell.Run(RunString & " >> " & LogFile & " 2>&1", 0, True)
RunString = "%comspec% /c %WINDIR%System32Defrag.exe " & DriveString &_
" -f"
Return = WshShell.Run(RunString & " >> " & LogFile & " 2>&1", 0, True)
SpaceSet = "%comspec% /c echo."
Return = WshShell.Run(SpaceSet, 0, True)
Return = WshShell.Run(SpaceSet, 0, True)
Return = WshShell.Run(SpaceSet, 0, True)
Set WshShell = Nothing
End Function
Function logEVT(logMe)
On Error Resume Next
Const EVENT_SUCCESS = 0
Dim objEShell
Set objEShell = WScript.CreateObject("Wscript.Shell")
objEShell.LogEvent 2, logMe
Set objEShell = Nothing
End Function

Now as you can see, this is not very readable. My first thought when I found this was literally “who the hell wrote this crap?”

Now, step one: get out of Notepad. Can this be done in Notepad? Absolutely. Does this code work? Absolutely. Am I crazy enough to actually try to read this code in black and white? Hell no.

Personally I like Notepad++ (http://notepad-plus.sourceforge.net/uk/site.htm), as I frequently work with 7-10 different scripting languages, and it does syntax highlighting for all of them. Trust me, once you use this tool, you’ll never use notepad again.

So once I’ve got the file open in Notepad++, I’m going to indent the code for readability. Now, let’s look at that code:

'SCRIPT........:  defragXP.vbs

'DATE..........:  09/06/2005
'AUTHOR........:  Joe Glessner
'DESCRIPTION...:  Defragments non removable volumes in XP using defrag.exe Logs results
'to the Application Event log on the local machine.
Const DriveTypeRemovable = 1
Const DriveTypeFixed = 2
Const DriveTypeNetwork = 3
Const DriveTypeCDROM = 4
Const DriveTypeRAMDisk = 5
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set Drives = objFSO.Drives
For Each Drive In Drives
If Drive.DriveType = 2 Then
    RunDfrg Drive
    logEVT("defragXP..:  Drive " & Drive & " defragmented.")
End If
Next
Function RunDfrg(DriveString)
    Set WshShell = WScript.CreateObject("WScript.Shell")
    RunString = "%comspec% /c echo " & WeekDayName(WeekDay(Now), True) &_
        " " & Now & " " & "Results for drive " & DriveString
    Return = WshShell.Run(RunString & " >> " & LogFile & " 2>&1", 0, True)
    RunString = "%comspec% /c %WINDIR%System32Defrag.exe " & DriveString &_
        " -f"
    Return = WshShell.Run(RunString & " >> " & LogFile & " 2>&1", 0, True)
    SpaceSet = "%comspec% /c echo."
    Return = WshShell.Run(SpaceSet, 0, True)
    Return = WshShell.Run(SpaceSet, 0, True)
    Return = WshShell.Run(SpaceSet, 0, True)
    Set WshShell = Nothing
End Function
Function logEVT(logMe)
    On Error Resume Next
    Const EVENT_SUCCESS = 0
    Dim objEShell
    Set objEShell = WScript.CreateObject("Wscript.Shell")
    objEShell.LogEvent 2, logMe
    Set objEShell = Nothing
End Function

Ok, that looks better, but to truly make this readable, we need some better commenting, and we need to make it pretty (for some reason I find scripts that are structured like the example below to be MUCH easier to read, than without the formatting).

In this example I’ve added some visual style, and some whitespace to break up the script so that it visually flows better (whitespace is “free”, the script processor ignores it, so feel free to make liberal use of it in your scripts):

'#=============================================================================
'#=============================================================================
'#  SCRIPT........:  defragXP.vbs
'#  VERSION.......:  1.1
'#  DATE..........:  09/06/2005
'#  AUTHOR........:  Joe Glessner
'#  EMAIL.........:  jglessner@gmail.com
'#  COPYRIGHT.....:  © 2005, NetTek Consulting And Design
'#  DESCRIPTION...:  Defragments non removable volumes in XP using defrag.exe
'#                   Logs results to the Application Event log on the local
'#                   machine.
'#=============================================================================
'#=============================================================================
'#  START CODE
'#=============================================================================
	'----------------------------------------------------------------------
	'#  Declare Variables
	'----------------------------------------------------------------------
	Const DriveTypeRemovable = 1
	Const DriveTypeFixed = 2
	Const DriveTypeNetwork = 3
	Const DriveTypeCDROM = 4
	Const DriveTypeRAMDisk = 5

	Set objFSO = CreateObject("Scripting.FileSystemObject")
        Set Drives = objFSO.Drives

	'#---------------------------------------------------------------------
	'#  Run defrag.exe on any "Fixed" HDDs
	'#---------------------------------------------------------------------
	For Each Drive In Drives
		If Drive.DriveType = 2 Then
		    RunDfrg Drive
                    logEVT("defragXP..:  Drive " & Drive & " defragmented.")
		End If
	Next

'#=============================================================================
'#  SUBROUTINES/FUNCTIONS/CLASSES
'#=============================================================================
    '#-------------------------------------------------------------------------
    '#  Function......:  RunDfrg
    '#  Use...........:  RunDfrg [DriveString]
    '#  Example.......:  RunDfrg c: [This will defrag the "C:\" drive]
    '#-------------------------------------------------------------------------
    Function RunDfrg(DriveString)
        Set WshShell = WScript.CreateObject("WScript.Shell")
        RunString = "%comspec% /c echo " & WeekDayName(WeekDay(Now), True) &_
            " " & Now & " " & "Results for drive " & DriveString
        Return = WshShell.Run(RunString & " >> " & LogFile & " 2>&1", 0, True)
        RunString = "%comspec% /c %WINDIR%System32Defrag.exe " & DriveString &_
            " -f"
        Return = WshShell.Run(RunString & " >> " & LogFile & " 2>&1", 0, True)
        SpaceSet = "%comspec% /c echo."
        Return = WshShell.Run(SpaceSet, 0, True)
        Return = WshShell.Run(SpaceSet, 0, True)
        Return = WshShell.Run(SpaceSet, 0, True)
        Set WshShell = Nothing
    End Function

    '#-------------------------------------------------------------------------
    '#  Function..........:  logEVT()
    '#  Use...............:  logEVT("Log message here.")
    '#  Purpose...........:  Logs specified text to the Windows Application
    '#                       Event Log.
    '#-------------------------------------------------------------------------
    Function logEVT(logMe)
        On Error Resume Next
        Const EVENT_SUCCESS = 0
        Dim objEShell
        Set objEShell = WScript.CreateObject("Wscript.Shell")
        objEShell.LogEvent 2, logMe
        Set objEShell = Nothing
    End Function

'#=============================================================================
'#  End CODE
'#=============================================================================

Now, when you compare this code to the original code, see the huge difference? If you want the full effect, copy this last code into a file called defragXP.vbs on your local hard drive, and open it with Notepad++. Syntax highlighting really does make a difference.

So now that you’ve seen the difference, let me share this with you: if you do this to your code, in six months (when you’ve forgotten the why’s and the how’s of a script) it will be FAR easier to figure out how the script functions, than if you hadn’t.

In the next post, I’ll show you how to use another script to pull the comments out of your scripts, so that you can make a sort of documentation file of the script (useful when trying to remember what you had to do in a script).

“The IT Ninja is an elusive creature. It is believed that only a handful of people have ever seen one, but none were able to describe them (mostly due to the witnesses having all been killed by a having single Travan tape embedded in their foreheads, almost as if the tapes were used as a shuriken…”

end

%d bloggers like this: