-
Notifications
You must be signed in to change notification settings - Fork 0
Guide System Commands
ARO provides the Exec action for executing shell commands on the host system. This chapter covers command execution, result handling, and security considerations.
The preferred syntax places the command name in the object specifier:
(* Simple command *)
Exec the <result> for the <command: "uptime">.
(* Command with arguments *)
Exec the <result> for the <command: "ls"> with "-la".
(* Command with multiple arguments *)
Exec the <result> for the <command: "ls"> with ["-l", "-a", "-h"].
This syntax clearly separates the command from its arguments, making code more readable.
The legacy syntax with full command in the with clause is still supported:
Exec the <result> for the <command> with "ls -la".
Exec the <listing> for the <files> with "find . -name '*.txt'".
Exec the <status> for the <check> with "git status".
Build commands dynamically with variables:
Create the <directory> with "/var/log".
Exec the <result> for the <command: "ls"> with "-la ${directory}".
Create the <pattern> with "*.aro".
Exec the <files> for the <command: "find"> with [". ", "-name", "${pattern}"].
Every Exec action returns a structured result object:
| Field | Type | Description |
|---|---|---|
error |
Boolean |
true if command failed (non-zero exit code) |
message |
String | Human-readable status message |
output |
String | Command stdout (or stderr if error) |
exitCode |
Int | Process exit code (0 = success, -1 = timeout) |
command |
String | The executed command string |
Exec the <result> for the <command> with "whoami".
(* Access individual fields *)
Log <result.output> to the <console>.
Log <result.exitCode> to the <console>.
(* Check for errors *)
Log <result.message> to the <console> when <result.error> = true.
(Check Disk Space: System Monitor) {
Exec the <result> for the <disk-check> with "df -h".
Log <result.message> to the <console> when <result.error> = true.
Return an <Error: status> with <result> when <result.error> = true.
Return an <OK: status> with <result>.
}
(Git Status: Version Control) {
Exec the <result> for the <git> with "git status --porcelain".
Log "Not a git repository" to the <console> when <result.exitCode> != 0.
Return a <BadRequest: status> with { error: "Not a git repository" } when <result.exitCode> != 0.
Return an <OK: status> with { message: "Working tree clean" } when <result.output> is empty.
Return an <OK: status> with { changes: <result.output> }.
}
Commands that exceed the timeout return with exitCode: -1:
Exec the <result> for the <long-task> with {
command: "sleep 60",
timeout: 5000
}.
Log "Command timed out" to the <console> when <result.exitCode> = -1.
For advanced control, use object syntax:
Exec the <result> on the <system> with {
command: "npm install",
workingDirectory: "/app",
timeout: 60000,
shell: "/bin/bash",
environment: { NODE_ENV: "production" }
}.
| Option | Type | Default | Description |
|---|---|---|---|
command |
String | (required) | The shell command to execute |
workingDirectory |
String | current | Working directory for the command |
timeout |
Int | 30000 | Timeout in milliseconds |
shell |
String | /bin/sh | Shell to use for execution |
environment |
Object | (inherited) | Additional environment variables |
captureStderr |
Boolean | true | Include stderr in output |
ARO's context-aware response formatting means Exec results display differently based on execution context.
command: ls -la
exitCode: 0
error: false
message: Command executed successfully
output:
total 48
drwxr-xr-x 12 user staff 384 Dec 23 10:00 .
-rw-r--r-- 1 user staff 1234 Dec 23 10:00 main.aro
{
"status": "OK",
"reason": "success",
"data": {
"result": {
"error": false,
"message": "Command executed successfully",
"output": "total 48\ndrwxr-xr-x 12 user staff...",
"exitCode": 0,
"command": "ls -la"
}
}
}(Application-Start: Directory Lister) {
Log "Directory Lister" to the <console>.
Exec the <listing> for the <command> with "ls -la".
Return an <OK: status> for the <listing>.
}
(System Info: Status API) {
Exec the <hostname> for the <command: "hostname">.
Exec the <uptime> for the <command: "uptime">.
Exec the <memory> for the <command: "free"> with "-h".
Create the <info> with {
hostname: <hostname.output>,
uptime: <uptime.output>,
memory: <memory.output>
}.
Return an <OK: status> with <info>.
}
(Run Build: CI Pipeline) {
Log "Installing dependencies..." to the <console>.
Exec the <install> for the <npm> with {
command: "npm install",
workingDirectory: "./app",
timeout: 120000
}.
Return an <Error: status> with <install> when <install.error> = true.
Log "Running tests..." to the <console>.
Exec the <test> for the <npm> with {
command: "npm test",
workingDirectory: "./app"
}.
Return an <Error: status> with <test> when <test.error> = true.
Log "Building..." to the <console>.
Exec the <build> for the <npm> with {
command: "npm run build",
workingDirectory: "./app"
}.
Return an <OK: status> with <build>.
}
(Health Check: Monitoring) {
Exec the <curl> for the <health> with {
command: "curl -s http://localhost:8080/health",
timeout: 5000
}.
Return a <ServiceUnavailable: status> with {
service: "api",
error: <curl.message>
} when <curl.error> = true.
Return an <OK: status> with { healthy: true }.
}
(List Processes: Admin API) {
Exec the <processes> for the <list> with "ps aux | head -20".
Return an <OK: status> with <processes>.
}
(Check Process: Admin API) {
Extract the <name> from the <queryParameters: name>.
Exec the <result> for the <check> with "pgrep -l ${name}".
Return an <OK: status> with { running: false, process: <name> } when <result.error> = true.
Return an <OK: status> with { running: true, process: <name>, pids: <result.output> }.
}
Be cautious when constructing commands from user input:
(* DANGEROUS - user input directly in command *)
Exec the <result> for the <command> with "ls ${userInput}".
(* SAFER - validate input first *)
Validate the <path> for the <userInput> against "^[a-zA-Z0-9_/.-]+$".
Return a <BadRequest: status> with "Invalid path characters" when <path> is not <valid>.
Exec the <result> for the <command> with "ls ${path}".
- Never trust user input - Always validate and sanitize before using in commands
- Use allowlists - Define allowed commands or patterns rather than blocking bad ones
- Limit permissions - Run the ARO application with minimal required privileges
- Set timeouts - Always specify reasonable timeouts to prevent hanging
- Log commands - Keep audit logs of executed commands for security review
Future versions may support sandboxing options:
Exec the <result> for the <command> with {
command: "npm install",
sandbox: {
network: false,
filesystem: ["/app"],
maxMemory: "512MB",
maxTime: 60000
}
}.
- File System - File I/O operations
- Services - Managing long-running services
- Error Handling - Handling errors gracefully
Fundamentals
- The Basics
- Feature Sets
- Actions
- Variables
- Type System
- Control Flow
- Error Handling
- Computations
- Dates
- Concurrency
Runtime & Events
I/O & Communication
Advanced