Click here to Skip to main content
14,970,948 members
Articles / Web Development / Node.js
Posted 25 Apr 2017



Shell Scripts for an Angular 2 Toolbox

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
25 Apr 2017CPOL7 min read
This article describes a handful of powerful shell scripts that I use to further automate my Angular 2 application development.


Even the most robust, well designed development environments almost always can stand a bit more automation.

As I moved past the tutorial, it took me almost no time to realize that I could significantly streamline the work with a dose of automation, in the form of shell scripts (Windows NT command scripts).


Throughout my long development career, I have endeavored to automate as many of the repetitive, error prone chores that take my attention away from the task at hand, especially those that involve steps that must be completed in a specific order. In the beginning, this automation consisted of little IBM JCL (Job Control Language) decks that I kept in my personal code repository. When I started working with personal computers, those JCL decks were replaced with batch files (now sometimes called shell scripts or Windows NT Command Scripts).

Over the last 5 years or so, it has become fashionable to use PowerShell for these kinds of tasks. Although I am quite confortable writing programs in C#, some of which found their way into this tool kit, PowerShell has a very steep learning curve, and is poorly suited to everyday use, unless you have ready access to commercial code signing certificates, and are willing to invest the time to use them in all of your scripts. Workarounds exist, but, by the time I could implement any of them, I could have my Windows NT command script written, tested, and in prodduction.

The package that accompanies this article contains nine shell scripts and programs (a mix of 32 bit native and managed code) that I use in my Angular work, summarized in the following table.

Tools in the Set
Date2FN.exeAppend LastWriteTime to file name.
LSNEWEST.BATReturn the name of the newest file that matches a wildcard specification. Several other scripts call this script.
MAKEZIP_DAG.CMDUse either WinZip or PK-Zip to make a backup archive of a directory.
SaveChromeDeveloperConsoleLog.CMDRun this script from a shortcut that sets its working directory to the directory where you want your collection of Chrome console logs. When you save the log, name it localhost.log; this script makes each file name unique.
StartAngularApp.CMDRun this script from a shortcut that sets its working directory to the directory where you created the Angular 2 application on which you want to work. The script will find the application source files extracted from the seed.
StartAngularDevWebServer.CMDBoth CreateNewAngularApp.CMD and StartAngularApp.CMD use this script to launch the Web server that comes with the Angular CLI. Since I haven't finished testing it, CreateNewAngularApp.CMD is omitted.
WWPause.exeThis robust replacement for the internal PAUSE command answers only to a Carriage Return or a CTRL-C.
wwsleep.EXEThis program is similar to sleep.exe, except that its memory footprint is quite a bit smaller.

There are two substantially identical Excel documents in the package.

  1. ToolboxInventory_Compact.XLSX contains one worksheet that is configured to show only the scripts and programs that you actually run.
  2. ToolboxInventory.xlsx contains one worksheet that lists evertyhing in the package, including the helper DLLs.

Both workbooks actually contain the same information, but ToolboxInventory_Compact.XLSX hides everything except the programs that you actually use. I'll leave you to discover for yourself how I did that.

Using the code

Most of the Windows NT command scripts are intended to be wired up to desktop shortcuts that leverage their Working Directory ("start in") properties to set the default directory against which to resolve relative path references.

Date2FN.exeWWPause.exe, and wwsleep.EXE are general purpose utility programs that can be put to all sorts of uses. I have many other scripts that use all three, and Date2FN.exe is pretty handy on its own as a command line utility.

Points of Interest

Classic batch file LSNEWEST.BAT is fairly straightforward. Its most unusual aspect is that it takes its input and returns its output through an environment variable, LSNEWEST, and that it uses the same varible for both. This is mostly a matter of engineering convenience, since environment variables are the only facility avaiilble for returning results from a function (subroutine).

for /f %%i in (%TEMP%\LSNEWEST.TMP) do set LSNEWEST=%%i
  1. The filespec in environment string LSNEWEST is fed to the internal dir command, which is instructed to return a bare listing of file names, sorted from oldest to newest by modified date.
  2. The list is read from %TEMP%\LSNEWEST.TMP, and LSNEWEST is updated with the file name, so that it contains the name of the newest file when control falls through the loop.
  3. The file list has done its job, and is discarded.

The %TEMP% environment variable holds the name of the user's temporary (scratch) directory, which is guaranteed to be writeable.

You will probably wire SaveChromeDeveloperConsoleLog.CMD up to a desktop shortcut. In addition to treatomg LSNEWEST.BAT as a subroutine, it calls an internal subroutine, fnglob, which takes two parameters, as follows.

call :fnglob LSNEWEST %SRCFN%

The first argument is LSNEWEST, a string literal, while SRCFN stores the value of the first (and only) argument, if any, or a default name for the Chrome console log, localhost.log. When fnglob returns, LSNEWEST has been transformed into an environemnt string of the same name that holds the glob that LSNEWEST.BAT needs.

Since it gets expanded as it passes into the subroutine, SRCFN, keeps its normal bounding tokens.

Date2FN.exe -r !SRCFN!
start !LSNEWEST!

While the unexpanded strings may be safely passed into fnglob, the next rhee commands require the delayed expansions imposed by the exclamation point tokens.

Function fnglob is mostly straightforward.

:fnglob <pglob> <pfilename>
    setlocal EnableDelayedExpansion
    set fnpath=%~dpn2
    set fnextn=%~x2
    set "fnglob=!fnpath!*!fnextn!"

    if "%_SaveChromeDeveloperConsoleLog%" equ "DEBUG" (
        echo -------------------------
        echo Within fnglob:
        echo Arg 1  = %1
        echo Arg 2  = %2
        echo fnpath = !fnpath!
        echo fnextn = !fnextn!
        echo fnglob = !fnglob!
        echo -------------------------

    if "%_SaveChromeDeveloperConsoleLog%" equ "DEBUG" (
        echo -------------------------
        echo Exiting fnglob:
        echo -------------------------
        echo fnglob = %fnglob%

    set "%~1=%fnglob%"
    exit /b

The two strings that appear in angle brackets next to the function's name, <pglob> <pfilename>, are parameters, which the batch file treats as comments.

Protected by another expansion delayed setlocal block, fnpath and fnextn are set to the input filespec up to the extension and the extension, itself, respectively. The next command constructs the string that becomes the value of the third environment variable, fnglob.

The code within the If block, if "%_SaveChromeDeveloperConsoleLog%" equ "DEBUG", generates a series of debugging messages, but only when environment variable _SaveChromeDeveloperConsoleLog is defined and has a value of DEBUG.  Since _SaveChromeDeveloperConsoleLog is defined only as needed, this block does nothing, unless you turn it on by defining and setting it.

The next to last statement in the final parenthetical block, set "%~1=%fnglob%", is responsible for returning the value by defining an environment variable with the name given in the first argument, and assigning to it the value of local environment variable fnglob. The enclosing quotations are required, but it's been so long since I devised this trick that I have long since forgotten why.

The last command is exit /b, where the /b instructs the command processor to return to the calling script, similar to return in most "real" programming languages. Unadorned, the exit command exits the entire script, not the intended outcome!

An alternative to exit /b is goto :eof, where eof is a virtual label that exists just past the last line of text in the script. I use both, although my more recent subrotines tend toward exit, because I think it's a tad clearer.

I'll wrap this section up with a couple of features of every one of these batch files.

@echo off
  1. Every script begins with the two commands shown above, the first of which suppresses command echo, including itself, and the next line goes to a script label, SKIPREM, a standard label that I almost always use.
  2. Jumping immediately to SKIPREM allows me to include a nice block of comments at the top of the script, including a revision history, and it permits any number of functions (subroutines) to be included at the top of the script, rather than at the end, as is a common proactice.
  3. The first command following the SKIPREM label is always echo BOJ %~0, version %~t0, which announces the name of the batch file, stripped of enclosing quotation marks, if any, followed by an evergreen version number comprised of the last modified date of the script file.
  4. Most, but by no means all, of my scripts next call ShowTime.CMD, which displays the current date and time. It's not the most polished display, because it doesn't bother to tweak the string at all, but it's effective.
  5. Finally, StartAngularApp.CMD and StartAngularDevWebServer.CMD make several calls into the Node Package Manager and variisous node.js packages, which happen actually to be Windows NT command scripts. To prevent their premature termination, these invocations must use CALL commands. The same goes for the code command that starts the Visual Studio Code editor, also a command script.


Wednesday, 26 April 2017 is the initial publication date.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

David A. Gray
Software Developer (Senior)
United States United States
I deliver robust, clean, adaptable, future-ready applications that are properly documented for users and maintainers. I have deep knowledge in multiple technologies and broad familiarity with computer and software technologies of yesterday, today, and tomorrow.

While it isn't perceived as sexy, my focus has always been the back end of the application stack, where data arrives from a multitude of sources, and is converted into reports that express my interpretation of The Fundamental Principle of Tabular Reporting, and are the most visible aspect of the system to senior executives who approve the projects and sign the checks.

While I can design a front end, I prefer to work at the back end, getting data into the system from outside sources, such as other computers, electronic sensors, and so forth, and getting it out of the system, as reports to IDENTIFY and SOLVE problems.

When presented with a problem, I focus on identifying and solving the root problem for the long term.

Specialties: Design: Relational data base design, focusing on reporting; organization and presentation of large document collections such as MSDS libraries

Development: Powerful, imaginative utility programs and scripts for automated systems management and maintenance

Industries: Property management, Employee Health and Safety, Services

Languages: C#, C++, C, Python, VBA, Visual Basic, Perl, WinBatch, SQL, XML, HTML, Javascript

Outside Interests: Great music (mostly, but by no means limited to, classical), viewing and photographing sunsets and clouds, traveling by car on small country roads, attending museum exhibits (fine art, history, science, technology), long walks, especially where there is little or no motor traffic, reading, especially nonfiction and thoughtfully written, thought provoking science fiction

Comments and Discussions

-- There are no messages in this forum --