# Process Module The `process` module provides functions for running external commands and managing system processes using a builder pattern for command execution. For running commands, you start with the `run()` function which returns a `CommandBuilder` object. You can then chain configuration methods like `silent()`, `ignore_error()`, and `log()` before finally calling the `do()` method to execute the command. By default, command execution using the builder (`.do()`) will halt the script execution if the command itself fails (returns a non-zero exit code) or if there's an operating system error preventing the command from running. You can change this behavior with `ignore_error()`. Other process management functions (`which`, `kill`, `process_list`, `process_get`) have specific error handling behaviors described below. --- ### `CommandResult` An object returned by command execution functions (`.do()`) containing the result of the command. - **Properties**: - `stdout`: `String` - The standard output of the command. - `stderr`: `String` - The standard error of the command. - `success`: `Boolean` - `true` if the command exited with code 0, `false` otherwise. - `code`: `Integer` - The exit code of the command. ```rhai let result = run("echo hi").do(); print(`Success: ${result.success}, Output: ${result.stdout}`); ``` --- ### `ProcessInfo` An object found by process listing/getting functions (`process_list`, `process_get`) containing information about a running process. - **Properties**: - `pid`: `Integer` - The process ID. - `name`: `String` - The name of the process executable. - `memory`: `Integer` - The memory usage of the process (unit depends on the operating system, typically KB or bytes). - `cpu`: `Float` - The CPU usage percentage (value and meaning may vary by operating system). ```rhai let processes = process_list("my_service"); if (processes.len() > 0) { let first_proc = processes[0]; print(`Process ${first_proc.name} (PID: ${first_proc.pid}) is running.`); } ``` --- ### `run(command)` Start building a command execution. - **Description**: Initializes a `CommandBuilder` for the given command string. This is the entry point to configure and run a process. - **Returns**: `CommandBuilder` - A builder object for configuring the command. - **Arguments**: - `command`: `String` - The command string to execute. Can include arguments and be a simple multiline script. ```rhai let cmd_builder = run("ls -l"); // Now you can chain methods like .silent(), .ignore_error(), .log() ``` --- ### `CommandBuilder:silent()` Configure the command to run silently. - **Description**: Suppresses real-time standard output and standard error from being printed to the script's console during command execution. The output is still captured in the resulting `CommandResult`. - **Returns**: `CommandBuilder` - Returns `self` for chaining. - **Arguments**: None. ```rhai print("Running silent command..."); run("echo This won\'t show directly").silent().do(); print("Silent command finished."); ``` --- ### `CommandBuilder:ignore_error()` Configure the command to ignore non-zero exit codes. - **Description**: By default, the `do()` method halts script execution if the command returns a non-zero exit code. Calling `ignore_error()` prevents this. The `CommandResult` will still indicate `success: false` and contain the non-zero `code`, allowing the script to handle the command failure explicitly. OS errors preventing the command from running will still cause a halt. - **Returns**: `CommandBuilder` - Returns `self` for chaining. - **Arguments**: None. ```rhai print("Running command that will fail but not halt..."); let result = run("exit 1").ignore_error().do(); // Will not halt if (!result.success) { print(`Command failed as expected with code: ${result.code}`); } ``` --- ### `CommandBuilder:log()` Configure the command to log the execution details. - **Description**: Enables logging of the command string before execution. - **Returns**: `CommandBuilder` - Returns `self` for chaining. - **Arguments**: None. ```rhai print("Running command with logging..."); run("ls /tmp").log().do(); // Will print the "ls /tmp" command before running print("Command finished."); ``` --- ### `CommandBuilder:do()` Execute the configured command. - **Description**: Runs the command with the options set by the builder methods. Waits for the command to complete and returns the `CommandResult`. This method is the final step in the command execution builder chain. Halts based on the `ignore_error()` setting and OS errors. - **Returns**: `CommandResult` - An object containing the output and status of the command. - **Arguments**: None. ```rhai print("Running command using builder..."); let command_result = run("pwd") .log() // Log the command .silent() // Don't print output live .do(); // Execute and get result (halts on error by default) print(`Command output: ${command_result.stdout}`); // Example with multiple options let fail_result = run("command_that_does_not_exist") .ignore_error() // Don't halt on non-zero exit (though OS error might still halt) .silent() // Don't print error live .do(); if (!fail_result.success) { print(`Failed command exited with code: ${fail_result.code} and stderr: ${fail_result.stderr}`); } ``` --- ### `which(cmd)` Check if a command exists in the system PATH. - **Description**: Searches the system's PATH environment variable for the executable `cmd`. This function does NOT halt if the command is not found; it returns an empty string. - **Returns**: `String` - The full path to the command executable if found, otherwise an empty string (`""`). - **Arguments**: - `cmd`: `String` - The name of the command to search for (e.g., `"node"`). ```rhai let node_path = which("node"); // Does not halt if node is not found if (node_path != "") { print(`Node executable found at: ${node_path}`); } else { print("Node executable not found in PATH."); } ``` --- ### `kill(pattern)` Kill processes matching a pattern. - **Description**: Terminates running processes whose names match the provided `pattern`. Uses platform-specific commands (like `pkill` or equivalent). Halts script execution on error interacting with the system process list or kill command. - **Returns**: `String` - A success message indicating the kill attempt finished. - **Arguments**: - `pattern`: `String` - A pattern to match against process names (e.g., `"nginx"`). ```rhai print("Attempting to kill processes matching 'my_service'..."); // Use with caution! kill("my_service"); // Halts on OS error during kill attempt print("Kill command sent."); ``` --- ### `process_list(pattern)` List processes matching a pattern (or all if pattern is empty). - **Description**: Lists information about running processes whose names match the provided `pattern`. If `pattern` is an empty string `""`, lists all processes. Halts script execution on error interacting with the system process list. Returns an empty array if no processes match the pattern. - **Returns**: `Array` of `ProcessInfo` - An array of objects, each containing `pid` (Integer), `name` (String), `memory` (Integer), and `cpu` (Float). - **Arguments**: - `pattern`: `String` - A pattern to match against process names, or `""` for all processes. ```rhai print("Listing processes matching 'bash'..."); let bash_processes = process_list("bash"); // Halts on OS error if (bash_processes.len() > 0) { print("Found bash processes:"); for proc in bash_processes { print(`- PID: ${proc.pid}, Name: ${proc.name}, CPU: ${proc.cpu}%, Memory: ${proc.memory}`); } } else { print("No bash processes found."); } ``` --- ### `process_get(pattern)` Get a single process matching the pattern (error if 0 or more than 1 match). - **Description**: Finds exactly one running process whose name matches the provided `pattern`. Halts script execution if zero or more than one process matches the pattern, or on error interacting with the system process list. - **Returns**: `ProcessInfo` - An object containing `pid` (Integer), `name` (String), `memory` (Integer), and `cpu` (Float). - **Arguments**: - `pattern`: `String` - A pattern to match against process names, expected to match exactly one process. ```rhai let expected_service_name = "my_critical_service"; print(`Getting process info for '${expected_service_name}'...`); // This will halt if the service isn't running, or if multiple services have this name let service_proc_info = process_get(expected_service_name); print(`Found process: PID ${service_proc_info.pid}, Name: ${service_proc_info.name}`); ```