Commands and files
Run commands in a sandbox with streamed output, as the default user or as root, and copy files in and out.
Running commands
pols exec web -- uname -a
pols exec web -- bash -lc 'cd app && npm ci && npm test'
pols exec web --root -- apt-get install -y postgresql-client
pols exec web --cwd /srv --env DEBUG=1 --timeout 1800 -- make
echo 'print(6 * 7)' | pols exec web --stdin -- python3
Everything after -- is the command and its arguments, passed as they are, without a shell. Wrap it in bash -lc '...' when you need pipes, redirections, cd, && or the login environment.
| Option | Meaning |
|---|---|
--root |
run as root instead of user |
--cwd DIR |
working directory; default the user’s home |
--env KEY=VALUE |
an extra environment variable for this command (repeatable) |
--timeout SECONDS |
stop the command after this long; default 600, at most 86,400 |
--stdin |
send this machine’s standard input to the command (up to 768 KiB) |
The output streams to your terminal as the command produces it, and pols exits with the command’s exit code. With --json, it waits instead and prints one document with stdout, stderr and exit_code.
The sandbox must be running. The command sees the sandbox’s own environment variables (from --env and --secret at creation) plus the ones you pass.
Over the API
POST /v1/sandboxes/{sandbox}/exec takes the command as an argument array:
{ "command": ["bash", "-lc", "npm test"], "cwd": "/home/user/app", "timeout_seconds": 900 }
Without special headers, the call waits for the command and returns its exit code and output, each stream capped at 4 MiB (truncated says when output was cut). Send Accept: application/x-ndjson to stream instead: the response is one JSON event per line, stdout and stderr chunks as they arrive, ending with an exit event with the exit code, or an error event. A non-zero exit code is a normal result, not an API error.
Copying files
pols cp ./app.tar.gz web:/home/user/app.tar.gz # upload
pols cp web:/var/log/syslog ./syslog # download
pols cp web:/etc/os-release - # to standard output
tar czf - src | pols cp - web:/home/user/src.tgz # from standard input
pols cp --root --mode 0755 ./setup.sh web:/usr/local/bin/setup
pols cp copies one file per call; for a directory, pack it with tar and copy the archive. Paths in the sandbox are absolute. Uploads are owned by user unless you pass --root, and get mode 0644 unless you pass --mode. The parent directory must exist. One upload can be up to 1 GiB.
Over the API, GET /v1/sandboxes/{sandbox}/files?path=... returns the file’s bytes (its permission bits are in the X-Pols-File-Mode header) and PUT with the same query writes them.