ESC
Type to search...
S
Soli Docs

System Functions

Execute commands directly from Soli. System.run / System.run_sync exec the program directly with no shell. Use System.shell / System.shell_sync (or backticks) when you explicitly want shell features.

System.run(command)

Runs a command asynchronously and returns a Future. No shell is invoked — arguments are passed verbatim, so metacharacters from user input do not get interpreted.

Parameters

  • command (String | Array<String>) - Either a whitespace-split string with no shell metacharacters, or an argv array [program, arg1, arg2, ...]. Use the array form whenever any argument may contain user-controlled values.

Returns

Future<Hash> - A future that resolves to:

  • stdout (String) - Standard output
  • stderr (String) - Standard error
  • exit_code (Int) - Exit code (0 for success)

Errors

Throws if the string form contains shell metacharacters (| > < & ; $ ( ) ` ' " * ? [ ] { } ~). Use System.shell() or pass an argv array.

Example

let result = System.run("echo hello")
# result is a Future

# Access properties directly (auto-resolves)
print(result.stdout)   # "hello"
print(result.exit_code) # 0

# Argv form — safe with user input, no shell expansion
let safe = System.run(["convert", filename, "out.png"])

# Or resolve manually
let output = await(result)
print(output["stdout"])

System.run_sync(command)

Runs a command synchronously (blocking) and returns the result immediately. Same shell-free semantics as System.run.

Parameters

  • command (String | Array<String>) - String (no metacharacters) or argv array.

Returns

Hash - Contains stdout, stderr, and exit_code.

Example

let result = System.run_sync(["ls", "-la"])
print(result["stdout"])
print(result["exit_code"])

System.shell(command)

Runs a command asynchronously through sh -c <command>. Use this when you explicitly want shell features (pipes, redirection, globbing, etc.).

Warning: Never pass unsanitised user input here — every metacharacter is interpreted by the shell. For commands built from user data, use System.run with an argv array. The smell/dangerous-server-builtin lint flags System.shell calls in app/controllers/, app/middleware/, and app/views/.

Parameters

  • command (String) - The shell command to execute

Returns

Future<Hash>

Example

let listing = System.shell("ls *.sl | wc -l")
print(listing.stdout)

System.shell_sync(command)

Synchronous variant of System.shell. Returns a Hash directly.

let result = System.shell_sync("grep pattern file.txt")
print(result["exit_code"])

Command Substitution

Backtick syntax is syntactic sugar for System.shell() — the literal command is sent through sh -c.

Example

# Simple command
let result = `echo hello`
print(result.stdout)  # "hello"

# Shell features work directly
let files = `ls *.sl`
print(files.stdout)

# Access exit code
let status = `grep pattern file`
if status.exit_code != 0
    println("Pattern not found")
end

Note: Backticks accept literal source-code commands only (no string interpolation). For commands that include user input, build an argv array and call System.run instead.

See Also