6.4.7 External execute, executeBlocking,
read
External commands, e.g. compilers, can be executed using the
External template:
external 'javac ' id '.java' execute
Again, all
output between external and execute keywords goes to building up the command to
be executed. For example, the command above would run a Java compiler on a .java
file named after the current object, e.g. ‘javac Stopwatch.java’.
There are different flavors for how the eternal command is
executed: see below.
external execute
Commands are executed immediately they are encountered, and
the generator continues executing without waiting for the command to return.
Execute forks a command processor, which will open a command prompt window
(shell terminal) for batch commands, or the GUI program for GUI executables,
documents and locations.
external executeBlocking
To block generator execution during the external command,
replace the final execute command with
an executeBlocking command,
i.e.
external 'javac ' id '.java' executeBlocking
Note
that executeBlocking can only work for
programs, i.e. something that exists as an executable (e.g. .exe, .com or .bat
on Windows); execute also works with
URLs, documents, and internal DOS commands such as
mkdir. To use
executeBlocking for non-programs, you
can make a command that invokes the platform’s command processor or a
script like metarun. E.g. the following
would work in Windows:
external 'start "" cmd /x /c mkdir NEW' executeBlocking
A
useful resource for command processors, batch files and shell scripts is
www.ss64.com.
external read
If your generator needs the output from an external command,
and you do not want a visible command prompt while the external command runs,
replace the final execute command with
a read command, i.e.
external 'javac ' id '.java' read
The
command’s output will be placed on the generator output stream, or you can
save it in a variable:
$javacOutput = __(external 'javac ' id '.java' read)
external..read
will block like executeBlocking, as the
generator needs to wait for the output. It is however like
external..execute in terms of the
commands it accepts on Windows: there is no need to prepend
cmd.exe /u /c, as that is already done
internally. On Windows, if the argument is a document rather than a command,
it will open that document and wait for the user to close it before returning:
prepend start "" to have it return
immediately, leaving the document open.
Note that the call will only return when the external
command has finished, so an invocation with just
cmd, or anything else that waits for
input, will start a command processor that never returns. You can interrupt in
MERL with the progress gauge Break button, and kill these cmd.exe instances from
Task Manager, possibly resulting in an error and/or opening the results in
MetaEdit+.
On non-Windows platforms,
external..read does not use
metarun or
metahelp (the MetaEdit+ helper scripts
that allow you to ‘run’ a document or URL), but you can of course
explicitly call
them.