Execute Shell Commands

You can invoke shell-commands during processing of a hsc source. The output of the command can be assigned to an special attribute or immediately being included into the document. This can be useful to include data from external applications (like databases), prepared by scripts (eg. Rexx), which of course you have to write yourself.

This functionality is provided by the hsc tag <$exec>

Possible Attributes

Specifies command to be executed. This attribute is required
If this attribute occurs, the output the command sends to stdout (or the filename specified with FILE) is included in the document.
Using this attribute, you can select an attribute you've created before using <$define> to store the data the command sends to stdout.
Specifies filename where the command is expected to store the output. The filename is relative to the source-directory. If this attribute is not set, hsc will assume the command to output to stdout and will redirect the output to a temporary file. This attribute is only useful if you have also set at least one of INCLUDE or ATTRIBUTE
This attribute has the same meaning as within <$include>. Note that it can be reasonable to specify it, even if you set a specific output-file, and not only for temporary-files created by hsc.
This attribute tells hsc what to do with the output-file after all data have been read. If you set it to REMOVE="off", the file will be left untouched. If no one else is going to remove it, it will continue to exist until doomsday or the next head-crash.

If you didn't specify an output filename (using FILE), this can clutter your temporary-directory (usually "t:") with loads of files having strange names like "hsc0x321764.tmp".

To avoid this, you can set REMOVE="on", so the output-file will always be removed.

By default, REMOVE="auto" is set. This will remove the file, if TEMPORARY has been enabled, and - if INCLUDE has been activated, too - no messages showed up during including the file.

Note: Never trust freeware-programmers when they start removing your files. So never use <$exec> on important data without any backup, and always use REMOVE="off" if your data are not really completely temporary.

Additionally, you can use all attributes of <$include> that change the appearance of the included data, like PRE, SOURCE etc. - Of course, this only makes sense if the INCLUDE-attribute has been set.

You can set both INCLUDE and ATTRIBUTE with one call to <$exec>.


<$exec COMMAND="dpaint">
Invokes Deluxe-Paint. Now you can paint whatever you like. When you quit the program, hsc will continue to process it's source. Note that this is not a very useful example.
List all hsc-sources in the current directory and include this list into the current document. The output of the list-command is redirected to a temporary file, which is removed afterwards.
<$exec COMMAND="echo Hello! >echo.tmp" TEMPORARY INCLUDE FILE="echo.tmp">
List all hsc-sources in the current directory and include this list into the current document. The output of the list-command is obviously redirected to a file called echo.tmp, which hsc tries to read because of the FILE-attribute.
<$define output:string>
<$exec COMMAND="list #?.hsc" ATTRIBUTE="output">
List all *.hsc-files in current directory and assign output to the attribute output; no data are included into the current document.

A More Complex Example

If you want to create a portable hsc source to insert a listing of a directory, you could try something like this:
<$elseif COND=(HSC.SYSTEM="UNIX")>
  <$message text="operating system not supported" class="warning">
And the data created by this code sequence would look like this:
drwxr-xr-x 9 diego diego 4096 Jun  5 18:15 .

Computing Complex Data

As hsc is only a simple preprocessor, but not a programming language, it can not do certain things. For example, there are no string functions. But you can use external commands to gain the same result.

The Rexx-script grafflwerk/StripNastyChars.rexx together with grafflwerk/StripNastyChars.hsc shows how to strip all but alpha numeric characters from a given string.

To better understand what StripNastyChars.rexx, you can first try to call it from the command line. Set your working directory to grafflwerk, and type:
rx StripNastyChars.rexx bla:sülz:fasel
results in
If you tried this yourself, you maybe noticed that the Rexx-script does not output a linefeed at the end of line. This is done by avoiding to use
SAY stripped
to display the converted data. Instead, you will find a
call WriteCH(stdout, stripped)
This simply is because StripNastyChars.hsc assigns the output of this script to a target attribute called clean-data by means of
<$exec command=("rx StripNastyChars.rexx " + nasty-data) ATTRIBUTE=clean-data>
Because of obvious reasons, the linefeed character created by SAY would be unwanted in the value of the target attribute. Therefor, the interesting part of the created HTML document will look like:
Converted "This#Text|Contains!Ñâ§ïÿ/Characters"
to        "ThisTextContainsCharacters".
It should be easy for you to put this functionality in a macro.


Technically speaking, hsc redirects the output of you command by appending a " >filename" to the command-string. For example, if you called

<$exec COMMAND="list #?.hsc" INCLUDE>

hsc will invoke the command like

list #?.hsc >hsc0x321764.tmp

with hsc0x321764.tmp chosen as temporary output file by hsc. If you specify the FILE attribute, you tell hsc where to expect the output. But now you are responsible to redirect it yourself. For example,

<$exec COMMAND="list #?.hsc >list.tmp"   INCLUDE FILE="list.tmp">
<$exec COMMAND="list #?.hsc TO list.tmp" INCLUDE FILE="list.tmp">

will both create an output in list.tmp, where hsc will also look for it. But the next one will fail:

<$exec COMMAND="list #?.hsc >list.tmp" FILE="tmp.list">

The reason is obvious: The command outputs to list.tmp, but hsc tries to read tmp.list, which most likely will not exist.

Another problem will occur, if you redirect the output yourself within the command call, but do not specify the FILE-attribute: hsc will try to redirect the output twice: For example,

<$exec COMMAND="list #?.hsc >list.tmp" INCLUDE>

will try to invoke something like

list #?.hsc >list.tmp >hsc0x321764.tmp

The behavior of this call is system dependent, but there's a general statement on this topic: it most likely won't work.