Skip to content
pols.so docs
Esc
↑↓navigate↵open⌘Jpreview
On this page

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.