6.1 KiB
SAL Process Module (sal::process
)
The process
module in the SAL (System Abstraction Layer) library provides a robust and cross-platform interface for creating, managing, and interacting with system processes. It is divided into two main sub-modules: run
for command and script execution, and mgmt
for process management tasks like listing, finding, and terminating processes.
Core Functionalities
1. Command and Script Execution (run.rs
)
The run.rs
sub-module offers flexible ways to execute external commands and multi-line scripts.
RunBuilder
The primary interface for execution is the RunBuilder
, obtained via sal::process::run("your_command_or_script")
. It allows for fluent configuration:
.die(bool)
: Iftrue
(default), an error is returned if the command fails. Iffalse
, aCommandResult
withsuccess: false
is returned instead..silent(bool)
: Iftrue
(default isfalse
), suppressesstdout
andstderr
from being printed to the console during execution. Output is still captured inCommandResult
..async_exec(bool)
: Iftrue
(default isfalse
), executes the command or script in a separate thread, returning an immediate placeholderCommandResult
..log(bool)
: Iftrue
(default isfalse
), prints a log message before executing the command..execute() -> Result<CommandResult, RunError>
: Executes the configured command or script.
Input Handling:
- Single-line commands: Treated as a command and its arguments (e.g.,
"ls -la"
). - Multi-line scripts: If the input string contains newline characters (
\n
), it's treated as a script.- The script content is automatically dedented.
- On Unix-like systems,
#!/bin/bash -e
is prepended (if no shebang exists) to ensure the script exits on error. - A temporary script file is created, made executable, and then run.
CommandResult
All execution functions return a Result<CommandResult, RunError>
. The CommandResult
struct contains:
stdout: String
: Captured standard output.stderr: String
: Captured standard error.success: bool
:true
if the command exited with a zero status code.code: i32
: The exit code of the command.
Convenience Functions:
sal::process::run_command("cmd_or_script")
: Equivalent torun("cmd_or_script").execute()
.sal::process::run_silent("cmd_or_script")
: Equivalent torun("cmd_or_script").silent(true).execute()
.
Error Handling:
RunError
: Enum for errors specific to command/script execution (e.g.,EmptyCommand
,CommandExecutionFailed
,ScriptPreparationFailed
).
2. Process Management (mgmt.rs
)
The mgmt.rs
sub-module provides tools for querying and managing system processes.
ProcessInfo
A struct holding basic process information:
pid: i64
name: String
memory: f64
(currently a placeholder)cpu: f64
(currently a placeholder)
Functions:
-
sal::process::which(command_name: &str) -> Option<String>
: Checks if a command exists in the system'sPATH
. Returns the full path if found.if let Some(path) = sal::process::which("git") { println!("Git found at: {}", path); }
-
sal::process::kill(pattern: &str) -> Result<String, ProcessError>
: Kills processes matching the givenpattern
(name or part of the command line). Usestaskkill
on Windows andpkill -f
on Unix-like systems.match sal::process::kill("my-server-proc") { Ok(msg) => println!("{}", msg), // "Successfully killed processes" or "No matching processes found" Err(e) => eprintln!("Error killing process: {}", e), }
-
sal::process::process_list(pattern: &str) -> Result<Vec<ProcessInfo>, ProcessError>
: Lists running processes, optionally filtering by apattern
(substring match on name). Ifpattern
is empty, lists all accessible processes. Useswmic
on Windows andps
on Unix-like systems.match sal::process::process_list("nginx") { Ok(procs) => { for p in procs { println!("PID: {}, Name: {}", p.pid, p.name); } }, Err(e) => eprintln!("Error listing processes: {}", e), }
-
sal::process::process_get(pattern: &str) -> Result<ProcessInfo, ProcessError>
: Retrieves a singleProcessInfo
for a process matchingpattern
. Returns an error if zero or multiple processes match.match sal::process::process_get("unique_process_name") { Ok(p) => println!("Found: PID {}, Name {}", p.pid, p.name), Err(sal::process::ProcessError::NoProcessFound(patt)) => eprintln!("No process like '{}'", patt), Err(sal::process::ProcessError::MultipleProcessesFound(patt, count)) => { eprintln!("Found {} processes like '{}'", count, patt); } Err(e) => eprintln!("Error: {}", e), }
Error Handling:
ProcessError
: Enum for errors specific to process management (e.g.,CommandExecutionFailed
,NoProcessFound
,MultipleProcessesFound
).
Examples
Running a simple command
use sal::process;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let result = process::run("echo 'Hello from SAL!'").execute()?;
println!("Output: {}", result.stdout);
Ok(())
}
Running a multi-line script silently
use sal::process;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let script = r#"
echo "Starting script..."
date
echo "Script finished."
"#;
let result = process::run(script).silent(true).execute()?;
if result.success {
println!("Script executed successfully. Output:\n{}", result.stdout);
} else {
eprintln!("Script failed. Error:\n{}", result.stderr);
}
Ok(())
}
Checking if a command exists and then running it
use sal::process;
fn main() -> Result<(), Box<dyn std::error::Error>> {
if process::which("figlet").is_some() {
process::run("figlet 'SAL Process'").execute()?;
} else {
println!("Figlet not found, using echo instead:");
process::run("echo 'SAL Process'").execute()?;
}
Ok(())
}