Command Execution
Command Execution
Section titled “Command Execution”Execute external commands and shell scripts with full control over I/O streams.
For executor configuration, see Executor.
Loading
Section titled “Loading”local exec = require("exec")Acquiring an Executor
Section titled “Acquiring an Executor”Get a process executor resource by ID:
local executor, err = exec.get("app:exec")if err then return nil, errend
-- Use executorlocal proc = executor:exec("ls -la")-- ...
-- Release when doneexecutor:release()| Parameter | Type | Description |
|---|---|---|
id | string | Resource ID |
Returns: Executor, error
Creating a Process
Section titled “Creating a Process”Create a new process with the specified command:
-- Simple commandlocal proc, err = executor:exec("echo 'Hello, World!'")
-- With working directorylocal proc = executor:exec("npm install", { work_dir = "/app/project"})
-- With environment variableslocal proc = executor:exec("python script.py", { work_dir = "/scripts", env = { PYTHONPATH = "/app/lib", DEBUG = "true", API_KEY = api_key }})
-- Run shell scriptlocal proc = executor:exec("./deploy.sh production", { work_dir = "/app/scripts", env = { DEPLOY_ENV = "production" }})| Parameter | Type | Description |
|---|---|---|
cmd | string | Command to execute |
options.work_dir | string | Working directory |
options.env | table | Environment variables |
Returns: Process, error
start / wait
Section titled “start / wait”Start the process and wait for completion.
local proc = executor:exec("./build.sh")
local ok, err = proc:start()if err then return nil, errend
local exit_code, err = proc:wait()if err then return nil, errend
if exit_code ~= 0 then return nil, errors.new("INTERNAL", "Build failed with exit code: " .. exit_code)endstdout_stream / stderr_stream
Section titled “stdout_stream / stderr_stream”Get streams to read process output.
local proc = executor:exec("./process-data.sh")
local stdout = proc:stdout_stream()local stderr = proc:stderr_stream()
proc:start()
-- Read all stdoutlocal output = {}while true do local chunk = stdout:read(4096) if not chunk then break end table.insert(output, chunk)endlocal result = table.concat(output)
-- Check for errorslocal err_output = {}while true do local chunk = stderr:read(4096) if not chunk then break end table.insert(err_output, chunk)end
local exit_code = proc:wait()
stdout:close()stderr:close()
if exit_code ~= 0 then return nil, errors.new("INTERNAL", table.concat(err_output))end
return resultwrite_stdin
Section titled “write_stdin”Write data to process stdin.
-- Pipe data to commandlocal proc = executor:exec("sort")local stdout = proc:stdout_stream()
proc:start()
-- Write inputproc:write_stdin("banana\napple\ncherry\n")proc:write_stdin("") -- Signal EOF
-- Read sorted outputlocal sorted = stdout:read()print(sorted) -- "apple\nbanana\ncherry\n"
proc:wait()stdout:close()signal / close
Section titled “signal / close”Send signals or close the process.
local proc = executor:exec("./long-running-server.sh")proc:start()
-- ... later, need to stop it ...
-- Graceful shutdown (SIGTERM)proc:close()
-- Or force kill (SIGKILL)proc:close(true)
-- Or send specific signallocal SIGINT = 2proc:signal(SIGINT)Permissions
Section titled “Permissions”Exec operations are subject to security policy evaluation.
| Action | Resource | Description |
|---|---|---|
exec.get | Executor ID | Acquire an executor resource |
exec.run | Command | Execute a specific command |
Errors
Section titled “Errors”| Condition | Kind | Retryable |
|---|---|---|
| Invalid ID | errors.INVALID | no |
| Permission denied | errors.INVALID | no |
| Process closed | errors.INVALID | no |
| Process not started | errors.INVALID | no |
| Already started | errors.INVALID | no |
See Error Handling for working with errors.