Commands API
TL;DR
The Commands API provides client.commands.exec() for running shell commands on remote
machines. Supports working directory, environment variables, timeout, and user options.
For long-running commands, use client.commands.stream() for real-time stdout/stderr.
Batch execution runs commands across multiple machines simultaneously. Async execution
lets you fire-and-forget commands and check results later.
Execute commands on remote machines.
How do I execute a command?
// Execute a shell command on a remote machine and await the result
const result = await client.commands.exec(
'machine-id',
'ls -la'
);What does the response look like?
// Structure returned by exec() β includes stdout, stderr, exit code, and timing
interface CommandResult {
stdout: string;
stderr: string;
exitCode: number;
duration: number; // milliseconds
}What execution options are available?
// Pass options to control working directory, env vars, timeout, and user
const result = await client.commands.exec(
'machine-id',
'npm install',
{
cwd: '/app', // Run from this directory
env: { NODE_ENV: 'production' }, // Inject environment variables
timeout: 60000, // Abort after 60 seconds
user: 'deploy', // Execute as this OS user
}
);What options can I set?
| Option | Type | Description |
|---|---|---|
cwd | string | Working directory |
env | object | Environment variables |
timeout | number | Timeout in milliseconds |
user | string | Run as user |
shell | string | Shell to use |
How do I stream command output?
For long-running commands:
// Open a streaming connection instead of waiting for the full result
const stream = client.commands.stream(
'machine-id',
'npm run build'
);
// Handle stdout chunks as they arrive
stream.on('stdout', (data) => {
process.stdout.write(data);
});
// Handle stderr chunks as they arrive
stream.on('stderr', (data) => {
process.stderr.write(data);
});
// Fires when the remote process exits
stream.on('exit', (code) => {
console.log('Exit code:', code);
});
// Send input to the remote process's stdin
stream.write('yes\n');
// Kill the command on the remote machine
stream.kill();How do I execute commands asynchronously?
Run commands without waiting:
// Fire-and-forget: returns a commandId you can poll later
const { commandId } = await client.commands.execAsync(
'machine-id',
'npm run long-task'
);
// Poll the command's current state
const status = await client.commands.status(commandId);
console.log(status.state); // 'running' | 'completed' | 'failed'
// Retrieve the full result once the command has finished
const result = await client.commands.result(commandId);How do I run commands on multiple machines?
Run on multiple machines:
// Execute the same command across several machines in parallel
const results = await client.commands.execBatch(
['machine-1', 'machine-2', 'machine-3'],
'apt update && apt upgrade -y'
);
// Iterate over per-machine results
for (const [machineId, result] of Object.entries(results)) {
console.log(`${machineId}: exit code ${result.exitCode}`);
}How do I run multi-line scripts?
Run multi-line scripts:
// Define a multi-line bash script as a template literal
const script = `
#!/bin/bash
set -e
cd /app
git pull
npm install
npm run build
pm2 restart all
`;
// Execute the entire script on the remote machine
const result = await client.commands.script(
'machine-id',
script
);How do I view command history?
// Retrieve past commands filtered by limit and date range
const history = await client.commands.history('machine-id', {
limit: 50,
since: new Date('2024-01-01'),
});
// Log each historical command's details
for (const cmd of history) {
console.log(cmd.command, cmd.exitCode, cmd.timestamp);
}How do I abort a running command?
// Start a streaming command so we can cancel it later
const stream = client.commands.stream(
'machine-id',
'npm run long-task'
);
// Send SIGTERM to the remote process after 30 seconds
setTimeout(() => {
stream.kill('SIGTERM');
}, 30000);Last updated on