Written from a line-by-line source review; every example output is from a real run.
Introduction
The process plugin lets you run external programs from the script: you can run a command and wait for it to finish, start a background process and query its state later, or capture a program's output. The plugin is cross-platform (Linux and Windows) and handle-based: background processes receive an integer identifier (a handle) by which they can be managed later.
Three kinds of start
The launching functions fall into three families. Run* runs the command and WAITS for it to finish, then returns the exit code (blocking). Start* launches the process in the BACKGROUND and returns a handle immediately — the script keeps running meanwhile. StartCapture* also starts in the background, but CAPTURES the process's output, which you can read later with OutputText / OutputBlob.
Command line, argv, and the -Ex variants
Each of the three families has several forms. The base form takes a single command line (interpreted by the system shell). The …Argv form takes the program and its arguments separately (variadic), so you need not fuss with quoting, and there is no risk of shell injection. The …Ex / …ArgvEx form can also set a working directory and environment variables for the command.
Loading the plugin
plugin "../plugins/print/PrintPlugin"; plugin "../plugins/process/ProcessPlugin";
A typical flow — capturing output
i32 $h;
string $out[1024];
$h = process.StartCapture("echo hello");
process.Wait($h);
$out = process.OutputText($h);
process.Close($h);What to know about every function (the basics)
Run* returns the command's exit code (0 = success); Start* / StartCapture* a positive handle.
Background-process handles must be freed with Close at the end; ExitCode only gives a result for an already-finished process (otherwise it fails).
OutputText / OutputBlob work only on a process started with StartCapture* that has already finished. OutputText fails on output containing a NUL byte (binary) — for that use OutputBlob.
Using a non-existent handle (or an already-closed handle) raises a runtime error. A wrong argument count or type also causes an error.
The …Argv form avoids shell interpretation: the program and every argument pass through exactly as you gave them — which is safer with user data.
QuoteArg produces platform-specific quoting (POSIX shell on Linux, cmd rules on Windows), so you can safely embed a value into a command line.
How to read the signatures
commandLine is a complete command line, handle is the identifier of a background process. The , ... in the signature marks a variable number of further arguments (the argv elements). The type after the -> arrow is the return type. For example, process.Run(commandLine) -> int takes a command line and returns the exit code.
Blocking run (Run)
Running the command and waiting for it to finish. The return value is the process's exit code (0 = success).
process.Run
process.Run(commandLine) -> int
Runs a command line on the system shell, waits for it to finish, and returns the exit code.
| Parameter | Type | Description |
|---|---|---|
| commandLine | string | The command line to run (interpreted by the shell). |
The process's exit code (0 = success).
printf("%d\n", process.Run("true"));
printf("%d\n", process.Run("exit 3"));0 3
For simple, one-off commands when you only care about success (the exit code), not the output. The program's output goes to the script's own output.
process.RunEx
process.RunEx(workDir, envText, commandLine) -> int
Like Run, but you can also set a working directory and environment variables.
| Parameter | Type | Description |
|---|---|---|
| workDir | string | The working directory (empty = the current one). |
| envText | string | Environment-variable overrides (empty = inherit from the parent). |
| commandLine | string | The command line to run. |
The process's exit code.
// runs in the /tmp directory
printf("%d\n", process.RunEx("/tmp", "", "pwd > /dev/null"));0
When the command must run from a particular directory, or with modified environment variables (for example a build step in the project folder).
process.RunArgv
process.RunArgv(program, ...) -> int
Runs a program with the given arguments (no shell), waits for it to finish, and returns the exit code.
| Parameter | Type | Description |
|---|---|---|
| program | string | The name or path of the program to run. |
| ... | string | The program's arguments, one by one. |
The process's exit code.
// no shell interpretation; the arguments pass through exactly
printf("%d\n", process.RunArgv("echo", "hi"));0
The safer variant of Run: no shell injection, because the program and arguments pass directly, without quoting. Prefer this for commands containing user data.
process.RunArgvEx
process.RunArgvEx(workDir, envText, program, ...) -> int
Like RunArgv, but with a working directory and environment variables.
| Parameter | Type | Description |
|---|---|---|
| workDir | string | The working directory (empty = the current one). |
| envText | string | Environment-variable overrides (empty = inherit). |
| program | string | The program to run. |
| ... | string | The program's arguments, one by one. |
The process's exit code.
printf("%d\n", process.RunArgvEx("/tmp", "", "echo", "hi"));0
The safest blocking form: shell-free argument passing, plus control of the working directory and environment in one step.
Background start (Start)
Starting the process in the background; returns a handle immediately, the script keeps running. The output goes to the script's own output.
process.Start
process.Start(commandLine) -> int
Starts a command in the background and returns a handle.
| Parameter | Type | Description |
|---|---|---|
| commandLine | string | The command line to run. |
The process handle (a positive integer).
i32 $h;
$h = process.Start("sleep 1");
// the script keeps running meanwhile...
process.Wait($h);
process.Close($h);(you manage it later via the handle)
To start longer operations in parallel, when the script need not wait for them to finish. The handle is managed by Wait/IsRunning/Terminate, and Close at the end.
process.StartEx
process.StartEx(workDir, envText, commandLine) -> int
Like Start, but with a working directory and environment variables.
| Parameter | Type | Description |
|---|---|---|
| workDir | string | The working directory (empty = the current one). |
| envText | string | Environment-variable overrides (empty = inherit). |
| commandLine | string | The command line to run. |
The process handle.
i32 $h;
$h = process.StartEx("/tmp", "", "sleep 1");
process.Wait($h);
process.Close($h);(you manage it later via the handle)
To start a background process from a given directory or with a modified environment — for example launching a service from its own folder.
process.StartArgv
process.StartArgv(program, ...) -> int
Starts a program in the background with the given arguments (no shell), and returns a handle.
| Parameter | Type | Description |
|---|---|---|
| program | string | The program to run. |
| ... | string | The program's arguments, one by one. |
The process handle.
i32 $h;
$h = process.StartArgv("sleep", "1");
process.Wait($h);
process.Close($h);(you manage it later via the handle)
To start a background process safely (no shell injection) when you do not need the output — only the fact of the run and its state.
process.StartArgvEx
process.StartArgvEx(workDir, envText, program, ...) -> int
Like StartArgv, but with a working directory and environment variables.
| Parameter | Type | Description |
|---|---|---|
| workDir | string | The working directory (empty = the current one). |
| envText | string | Environment-variable overrides (empty = inherit). |
| program | string | The program to run. |
| ... | string | The program's arguments, one by one. |
The process handle.
i32 $h;
$h = process.StartArgvEx("/tmp", "", "sleep", "1");
process.Wait($h);
process.Close($h);(you manage it later via the handle)
The most flexible background start: shell-free arguments, working directory, and environment together.
Output-capturing start (StartCapture)
Like Start, but it captures the process's output, which OutputText / OutputBlob read later.
process.StartCapture
process.StartCapture(commandLine) -> int
Starts a command in the background and CAPTURES its output; returns a handle.
| Parameter | Type | Description |
|---|---|---|
| commandLine | string | The command line to run. |
The process handle (a positive integer).
i32 $h;
string $out[256];
$h = process.StartCapture("echo captured-line");
process.Wait($h);
$out = process.OutputText($h);
printf("%s", $out);
process.Close($h);captured-line
When you need a program's output (not just its exit code) — for example to process the result of a command. After Wait, OutputText/OutputBlob gives the output.
process.StartCaptureEx
process.StartCaptureEx(workDir, envText, commandLine) -> int
Like StartCapture, but with a working directory and environment variables.
| Parameter | Type | Description |
|---|---|---|
| workDir | string | The working directory (empty = the current one). |
| envText | string | Environment-variable overrides (empty = inherit). |
| commandLine | string | The command line to run. |
The process handle.
i32 $h;
$h = process.StartCaptureEx("/tmp", "", "pwd");
process.Wait($h);
printf("%s", process.OutputText($h));
process.Close($h);/tmp
To capture output from a given directory or with a modified environment — for example a command's output in the context of a particular working folder.
process.StartCaptureArgv
process.StartCaptureArgv(program, ...) -> int
Starts a program in the background with arguments (no shell), and captures its output.
| Parameter | Type | Description |
|---|---|---|
| program | string | The program to run. |
| ... | string | The program's arguments, one by one. |
The process handle.
i32 $h;
$h = process.StartCaptureArgv("echo", "hi");
process.Wait($h);
printf("%s", process.OutputText($h));
process.Close($h);hi
To capture output safely (no shell injection) when the arguments may come from user data.
process.StartCaptureArgvEx
process.StartCaptureArgvEx(workDir, envText, program, ...) -> int
Like StartCaptureArgv, but with a working directory and environment variables.
| Parameter | Type | Description |
|---|---|---|
| workDir | string | The working directory (empty = the current one). |
| envText | string | Environment-variable overrides (empty = inherit). |
| program | string | The program to run. |
| ... | string | The program's arguments, one by one. |
The process handle.
i32 $h;
$h = process.StartCaptureArgvEx("/tmp", "", "echo", "hi");
process.Wait($h);
printf("%s", process.OutputText($h));
process.Close($h);hi
The most complete form: capturing output, shell-free arguments, working directory, and environment together.
Process management
Querying, awaiting, reading the output of, terminating, and closing background processes by handle.
process.IsRunning
process.IsRunning(handle) -> int
Tells whether the process is still running.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The process handle. |
1 if it is still running; 0 if it has already finished.
i32 $h;
$h = process.StartCapture("echo x");
process.Wait($h);
printf("%d\n", process.IsRunning($h));
process.Close($h);0
For a non-blocking check of a background process's state (for example in a loop), without waiting for it to finish.
process.Wait
process.Wait(handle) -> int
Waits until the process finishes and returns its exit code.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The process handle. |
The process's exit code.
i32 $h;
$h = process.StartCapture("echo x");
printf("%d\n", process.Wait($h));
process.Close($h);0
When the script must wait for the background process to finish before processing its output or continuing.
process.WaitMs
process.WaitMs(handle, milliseconds) -> int
Waits at most the given time for the process to finish (does not block forever).
| Parameter | Type | Description |
|---|---|---|
| handle | int | The process handle. |
| milliseconds | int | The maximum wait time in milliseconds (0 = an immediate check). |
1 if the process finished within the time limit; 0 if it is still running.
i32 $h;
$h = process.StartCapture("echo x");
process.Wait($h);
printf("%d\n", process.WaitMs($h, 0));
process.Close($h);1
For a time-limited wait: so the script does not hang forever on a slow process. With 0 milliseconds you get an immediate, non-blocking state check.
process.ExitCode
process.ExitCode(handle) -> int
Returns the exit code of an already-finished process.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The process handle. |
The exit code. If the process is still running, a runtime error.
i32 $h;
$h = process.StartCapture("echo x");
process.Wait($h);
printf("%d\n", process.ExitCode($h));
process.Close($h);0
To query the exit code after the process has finished (after Wait or IsRunning=0). It fails on a still-running process — wait for it first.
process.OutputText
process.OutputText(handle) -> string
Returns the captured output of a finished process started with StartCapture*, as text.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The process handle. |
The captured output as text. Output containing a NUL byte (binary) causes a runtime error.
i32 $h;
$h = process.StartCapture("echo captured-line");
process.Wait($h);
printf("%s", process.OutputText($h));
process.Close($h);captured-line
To process textual program output (a command's result, a list, a status). If the output may be binary (may contain 0 bytes), OutputBlob is correct.
process.OutputBlob
process.OutputBlob(handle) -> blob
Returns the captured output of a finished process started with StartCapture*, as a raw blob.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The process handle. |
The captured output as a blob (the 0 byte is preserved).
i32 $h;
blob $out[256];
$h = process.StartCapture("echo hi");
process.Wait($h);
$out = process.OutputBlob($h);
printf("%d\n", $out.Length);
process.Close($h);3
To capture binary program output (an image, compressed data, a raw byte stream), where the 0 byte also matters — OutputText would reject it.
process.Terminate
process.Terminate(handle) -> int
Forcibly stops a still-running process.
| Parameter | Type | Description |
|---|---|---|
| handle | int | The process handle. |
Always 1.
i32 $h;
$h = process.Start("sleep 30");
printf("%d\n", process.Terminate($h));
process.Close($h);1
To forcibly stop a stuck or overrunning background process. Call Close afterwards too, to free the handle.
process.Close
process.Close(handle) -> int
Frees the process handle and its associated resources (such as the temporary file of the captured output).
| Parameter | Type | Description |
|---|---|---|
| handle | int | The handle to free. |
Always 1.
i32 $h;
$h = process.StartCapture("echo x");
process.Wait($h);
printf("%d\n", process.Close($h));1
Close every Start*/StartCapture* handle when you are done with it — otherwise the temporary files of captured output and the process entries can pile up.
Helper
Safely quoting an argument for a command line.
process.QuoteArg
process.QuoteArg(text) -> string
Puts the text into a safe form with quoting/escaping so it can be embedded as a single argument in a command line (per platform-specific rules).
| Parameter | Type | Description |
|---|---|---|
| text | string | The text to quote. |
The quoted text (POSIX shell on Linux, cmd rules on Windows).
printf("%s\n", process.QuoteArg("a b"));'a b'
When you do use the command-line (not …Argv) form and must safely embed a user value: QuoteArg protects spaces and special characters. Where possible, prefer the …Argv form, which needs no quoting at all.
Practical notes
What the process plugin is good for
Running external tools and commands from the script (a build step, a system command, a utility).
Managing background processes: starting, state-watching, awaiting, stopping.
Capturing and processing a program's output (a command's result, generated data).
Safe command assembly from user data with the …Argv form or QuoteArg.
Which form to choose
If you only care about success (the exit code) and do not need the output, Run* is the simplest. If the script must run in parallel with the process, Start* is appropriate. If you also need the program's output, StartCapture* is the choice. In all three families: if you pass user data, the …Argv form is safer (no shell injection), and …Ex gives control of the working directory and environment.
Lifecycle
Background processes (Start*/StartCapture*) return a handle that must be freed with Close at the end. The typical order: start → (perhaps IsRunning/WaitMs for the state) → Wait to await → ExitCode and/or OutputText/OutputBlob for the result → Close. In a long-running script, close every handle so resources do not pile up.
Text vs blob output
OutputText is for textual output, and it rejects output containing a NUL byte (binary). If the program writes binary data (or you are not sure it is textual), OutputBlob is correct, since it returns the raw bytes, including the 0 byte.
Error handling
A wrong argument count or type, a non-existent or already-closed handle, ExitCode called on a still-running process, and OutputText called on output containing a NUL byte are reported by the runtime as a runtime error, and the script stops. The usual states are signaled by a neutral return value: IsRunning and WaitMs give 0/1, Run* gives the exit code. Check a command's success by the exit code (Run*/ExitCode).
The tls encrypted-connection plugin
TLS client, server, and certificate handling (OpenSSL) — complete function reference