sal/docs/process/process.md
2025-05-08 09:54:20 +03:00

8.5 KiB

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.
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).
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.
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.
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.
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.
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.
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").
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").
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.
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.
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}`);