on
Execute commands on SSH hosts.
Synopsisβ
xec on [options] <hosts> [command...]
Descriptionβ
The on
command executes commands, scripts, or tasks on remote SSH hosts. It provides unified SSH execution with support for parallel operations, pattern matching, and direct SSH connections.
Argumentsβ
<hosts>
- SSH host specification (patterns supported)[command...]
- Command to execute (optional for REPL/interactive modes)
Host Specificationβ
Hosts can be specified as:
hosts.name
- Configured SSH hosthosts.*
- All configured SSH hostshosts.web-*
- Pattern matching{hosts.web1,hosts.web2}
- Multiple specific hostsuser@hostname
- Direct SSH connectionhostname
- Direct connection (uses current user)
Optionsβ
General Optionsβ
-p, --profile <profile>
- Configuration profile to use-i, --interactive
- Interactive mode for selecting hosts and options--task <task>
- Execute a configured task on the hosts--repl
- Start a REPL session with $target available-t, --timeout <duration>
- Command timeout (e.g., 30s, 5m)-e, --env <key=value>
- Environment variables (can be used multiple times)-d, --cwd <path>
- Working directory on remote host-u, --user <user>
- User to run command as (overrides config)--parallel
- Execute on multiple hosts in parallel--max-concurrent <n>
- Maximum concurrent executions (default: 10)--fail-fast
- Stop on first failure in parallel mode-v, --verbose
- Enable verbose output-q, --quiet
- Suppress output--dry-run
- Preview execution without running
Examplesβ
Basic Command Executionβ
Execute simple commands on SSH hosts:
# Single host
xec on hosts.web-1 "uptime"
# Multiple hosts with pattern
xec on hosts.web-* "df -h"
# All SSH hosts
xec on hosts.* "date"
# Direct SSH connection
xec on deploy@server.com "ls -la"
Parallel Executionβ
Run commands on multiple hosts simultaneously:
# Check service status on all web servers
xec on hosts.web-* "systemctl status nginx" --parallel
# Deploy to multiple servers
xec on hosts.app-* "./deploy.sh" --parallel --max-concurrent 5
# Stop on first failure
xec on hosts.* "npm test" --parallel --fail-fast
Script Executionβ
Run scripts with SSH context:
# Execute TypeScript script
xec on hosts.db-master ./scripts/backup.ts
# Execute JavaScript file
xec on hosts.worker ./migrate.js
# Script with $target context
xec on hosts.app ./deploy-script.js
Task Executionβ
Run configured tasks on hosts:
# Run deploy task
xec on hosts.production --task deploy
# Run backup task on all databases
xec on hosts.db-* --task backup --parallel
# Run health check task
xec on hosts.* --task health-check
REPL Modeβ
Start REPL with SSH context:
# Start REPL for single host
xec on hosts.dev --repl
# Access host in REPL
# > await $target`ls -la`
# > const mem = await $target`free -m`
Interactive Modeβ
Use interactive prompts for configuration:
# Interactive host selection and execution
xec on --interactive
# Prompts for:
# - Host selection (single/multiple)
# - Execution type (command/script/task/REPL)
# - Execution options (parallel, timeout, etc.)
Environment Variablesβ
Set environment variables for remote execution:
# Single variable
xec on hosts.app -e NODE_ENV=production "node server.js"
# Multiple variables
xec on hosts.worker -e DB_HOST=localhost -e DB_PORT=5432 "./process.sh"
# Override PATH
xec on hosts.build -e PATH=/custom/bin:$PATH "which node"
Working Directoryβ
Set remote working directory:
# Change to specific directory
xec on hosts.app -d /var/www/html "git pull"
# Run from user home
xec on hosts.backup -d ~ "./backup.sh"
# Temporary directory
xec on hosts.temp -d /tmp "rm -rf old-files-*"
Timeout Controlβ
Set execution timeouts:
# 30 second timeout
xec on hosts.test -t 30s "npm test"
# 5 minute timeout for longer operations
xec on hosts.build -t 5m "make all"
# 1 hour for backup operations
xec on hosts.backup -t 1h "./full-backup.sh"
User Overrideβ
Execute as different user:
# Run as root
xec on hosts.app -u root "apt-get update"
# Run as deploy user
xec on hosts.production -u deploy "./deploy.sh"
# Override configured user
xec on hosts.db -u postgres "psql -c 'SELECT version()'"
Advanced Usageβ
Pattern Matchingβ
Use patterns to select multiple hosts:
# Wildcard matching
xec on hosts.web-* "nginx -t"
# Brace expansion
xec on {hosts.web1,hosts.web2,hosts.db1} "uptime"
# All hosts
xec on hosts.* "uname -a"
# Complex patterns
xec on "hosts.{prod,staging}-web-*" "systemctl status"
Direct SSH Connectionsβ
Connect to hosts not in configuration:
# User@host format
xec on admin@192.168.1.100 "ls -la"
# Hostname only (uses current user)
xec on example.com "date"
# Multiple direct connections
xec on user@host1,user@host2 "uptime" --parallel
Parallel Execution Controlβ
Fine-tune parallel execution:
# Limited concurrency
xec on hosts.* "heavy-task.sh" --parallel --max-concurrent 3
# Fail fast on error
xec on hosts.prod-* "test.sh" --parallel --fail-fast
# Progress reporting
xec on hosts.* "backup.sh" --parallel -v
Command Chainingβ
Execute multiple commands:
# Sequential commands
xec on hosts.app "cd /app && git pull && npm install && npm run build"
# Conditional execution
xec on hosts.db "pg_isready && pg_dump mydb > backup.sql"
# Pipe operations
xec on hosts.log "tail -f /var/log/app.log | grep ERROR"
Script Contextβ
Scripts have access to SSH context:
// deploy.js
const hostname = await $target`hostname`;
console.log(`Deploying to ${hostname.stdout.trim()}`);
await $target`cd /app && git pull`;
await $target`npm install`;
await $target`npm run build`;
Configurationβ
Configure SSH hosts in .xec/config.yaml
:
targets:
hosts:
web-1:
type: ssh
host: 192.168.1.10
username: deploy
port: 22
privateKey: ~/.ssh/id_rsa
db-master:
type: ssh
host: db.example.com
username: admin
password: $SSH_PASSWORD # From environment
bastion:
type: ssh
host: bastion.example.com
username: jump
# SSH config for ProxyJump handled
commands:
on:
parallel: true
maxConcurrent: 10
timeout: "1m"
SSH Featuresβ
Connection Optionsβ
The command respects SSH configuration:
# Uses SSH config file
xec on hosts.configured "date"
# Direct connection with defaults
xec on new-host.com "uptime"
# Connection pooling for efficiency
xec on hosts.* "quick-check" --parallel
Authenticationβ
Supports multiple authentication methods:
- SSH keys (preferred)
- SSH agent
- Password authentication
- SSH config ProxyJump
Connection Poolingβ
Connections are pooled for efficiency:
- Reuses existing connections
- Parallel commands share connections
- Automatic cleanup on exit
Error Handlingβ
The command handles SSH errors gracefully:
- Connection refused
- Authentication failed
- Host unreachable
- Command not found
- Permission denied
- Timeout exceeded
Use -v, --verbose
for detailed error information.
Performance Considerationsβ
- Connection pooling reduces overhead
- Parallel execution for multiple hosts
- Streaming for large outputs
- Efficient for batch operations
Security Notesβ
- SSH keys preferred over passwords
- Passwords read from environment variables
- Sensitive data not logged
- Respects SSH known_hosts
Troubleshootingβ
Connection Issuesβ
# Test SSH connection
ssh -v user@host
# Check SSH config
cat ~/.ssh/config
# Verify host key
ssh-keyscan hostname
Authentication Problemsβ
# Check SSH agent
ssh-add -l
# Test with specific key
xec on hosts.server "date"
# Check config for correct key path
Timeout Issuesβ
# Increase timeout for slow connections
xec on hosts.remote -t 5m "long-running-task"
# Check network latency
ping hostname
Related Commandsβ
Exit Codesβ
0
- Success1
- General error2
- Invalid arguments3
- Host not found4
- SSH connection failed5
- Command execution failed124
- Timeout exceeded