Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SFTP Workflows

sshx supports one-shot SFTP actions for common file tasks. It is not an interactive file manager; each invocation performs one clear upload, download, list, mkdir, or remove operation.

Plans and effect evidence

SFTP and server-to-server transfer accept --dry-run --json, --expect-plan, --host-timeout and --global-timeout. Dry-run is offline and write-free. Binding checks the public endpoints/operation and local upload payload, not unread remote content or recursive directory membership.

Use --json to consume the CLI operation result, shared execution identity, effects, change_state, nullable executed, and verification status. Size/metadata evidence is not a content-digest guarantee. Downloads record local writes even when the remote operation is risk=read; relay reads the source and writes the destination.

The operation result includes entries, bytes_transferred, partial, and directory_atomic (false). Each entry records its path/type/size/mode, copied bytes, started/published state and verification; content-checked file copies also expose source_sha256 / sha256. Known staging/cleanup evidence is retained as staging_path / cleanup_error on errors. Use the actual entry verification rather than assuming every operation (such as listing) has content hashes.

Upload/relay stage each file before publication. Overwriting an existing remote destination requires supported atomic replacement; when unavailable, fail without deleting that destination. Ordinary SFTP rename can publish a new destination. Downloads stage beside the local destination and use the local OS’s rename semantics; POSIX guarantees are not assumed on Windows. After connection loss, remote staging cleanup may be impossible and is reported. The publication methods are posix_rename, new-file sftp_rename_no_replace, and download local_rename. Successful file verification includes post-copy readback SHA-256 and metadata; mkdir verifies type/existence, removal verifies absence, and listing supplies metadata only. Earlier published entries remain in a partial result if a later directory entry fails.

Single-file staging, where supported, does not provide directory-wide atomicity, arbitrary-writer CAS, or automatic rollback. A failed/interrupted recursive transfer can have partial destination effects; inspect before retrying. See Plans, Outcomes, and Safe Retries.

Upload A File

sshx -h=prod-web --upload=./deploy/nginx.conf --to=/tmp/nginx.conf

To overwrite an existing remote file with a backup and hash precondition, use Guarded File Apply instead of assembling upload + install yourself:

sshx apply -h=prod-web --path=/etc/nginx/nginx.conf --from=./deploy/nginx.conf --sudo --json
sshx run --target=prod-web --json -- "sudo nginx -t"

Download A File

sshx -h=prod-web --download=/var/log/nginx/error.log --to=./error.log

Incident collection example:

mkdir -p incident-2026-07-01/prod-web
sshx -h=prod-web --download=/var/log/nginx/error.log --to=incident-2026-07-01/prod-web/error.log
sshx -h=prod-web --download=/etc/os-release --to=incident-2026-07-01/prod-web/os-release

List And Create Directories

sshx -h=prod-web --list=/var/log
sshx -h=prod-web --mkdir=/tmp/sshx-upload

Remove A Remote File

sshx -h=prod-web --rm=/tmp/old-upload.txt

Treat remote deletion as production change. Prefer listing the parent directory first:

sshx -h=prod-web --list=/tmp
sshx -h=prod-web --rm=/tmp/old-upload.txt

Path Boundary

Local paths use your local operating system rules. Remote paths are SFTP paths and should be written as slash-separated remote paths, even when sshx is run from Windows.

# Local Windows path, remote POSIX path
sshx -h=prod-web --upload=C:\Users\alice\release.zip --to=/tmp/release.zip

When To Use Plain SSH Instead

Use an SSH command when the operation needs remote validation or privilege changes:

sshx -h=prod-web "sudo ls -l /etc/nginx"
sshx -h=prod-web "sudo install -m 0644 /tmp/nginx.conf /etc/nginx/nginx.conf"

Use SFTP for direct file movement. Use remote commands for checks, ownership changes, service reloads, and cleanup that requires sudo.