Execute commands in a VM¶
Just like copying files in and out of a VM, executing commands can be done in several ways:
- Initially, via a userdata script or userdata file specified in the host group or via the API/CLI create command after Slicer has been started.
- Through SSH assuming direct network access is available to the VM via the LAN or a VPN.
- Through Slicer's REST API - using your own client, the SDK or the
slicerCLI.
The exec command allows you to run commands remotely on VMs. The first argument is the instance to run the commands on, -- optionally separates the slicer CLI options from the command to run on the VM.
# Run a command as root (default)
slicer vm exec vm-1 whoami
# Run command as non-root user (UID 1000)
slicer vm exec vm-1 --uid 1000 whoami
Change the working directory and run commands with arguments:
# Execute command in specific directory
slicer vm exec vm-1 --cwd /var/log -- ls -la
Control shell interpretation for complex commands:
# Use default bash shell for complex commands with pipes
slicer vm exec vm-1 -- "ls -l | sort"
# Use custom shell interpreter
slicer vm exec vm-1 --shell /bin/zsh -- "echo $SHELL"
# Execute directly without shell (faster for simple commands)
slicer vm exec vm-1 --shell "" whoami
Combine with local commands using pipes and STDIO:
# Pipe local file content to VM command
cat /etc/hostname | slicer vm exec vm-1 -- base64 --wrap 9999
Streaming vs buffered exec via the REST API¶
The /vm/{hostname}/exec REST endpoint ships two response shapes:
- Streaming (default) — NDJSON frames as output arrives. Preferred
for long-running commands where you want live stdout/stderr, or when
you want to measure process-start latency separately from first-byte
latency using the typed
startedframe. - Buffered — add
buffered=trueto get a single JSON document withstdout,stderr, andexit_codeonce the process exits. Preferred for short "run one thing, give me the result" calls; avoids the need for client-side NDJSON parsing.
# Streaming (default)
curl --unix-socket ~/slicer-mac/slicer.sock \
-X POST "http://localhost/vm/vm-1/exec?cmd=uname&args=-a"
# Buffered
curl --unix-socket ~/slicer-mac/slicer.sock \
-X POST "http://localhost/vm/vm-1/exec?buffered=true&cmd=uname&args=-a"
# → {"stdout":"Linux vm-1 ...\n","stderr":"","exit_code":0}
buffered=true does not accept stdin; use the streaming endpoint if
you need to pipe stdin data.