Move files and directories between your machine and a registered SSH target with scp, addressing the remote side as target:path instead of user@host.
pks ssh copy <SOURCE> <DEST> [options]$ pks ssh copy ./build.tar hetzner:~/build.tarUpload a file to a target
$ pks ssh copy hetzner:~/out.json ./out.jsonDownload a file from a target
$ pks ssh copy ./dist hetzner:~/dist --recursiveUpload a directory tree
pks ssh copy transfers files and directories over scp, with the remote side written as <target>:<path>. The target part is resolved from the registry the same way connect and run resolve it, so the label replaces the full user, host, port, and identity.
scp binary on PATH. copy shells out to it directly.copy uses BatchMode=yes, so no passphrase prompt is possible.ssh.connect guard applies to copy as well.pks ssh copy ./build.tar hetzner:~/build.tar
Exactly one of SOURCE and DEST must resolve to a registered target. Both remote or neither remote is rejected with an explicit error.
pks ssh copy hetzner:~/out.json ./out.json
The remote spec goes in the source position; the local path in the destination.
pks ssh copy ./dist hetzner:~/dist --recursive
Without -r, scp refuses a directory.
Confirm the file landed on the far side:
pks ssh run hetzner -- "ls -l ~/build.tar"
The listing prints the expected size.
| Flag | Description |
|---|---|
-r, --recursive | Recurse into directories. |
| Argument | Required | Description |
|---|---|---|
SOURCE | yes | Source path — local, or <target>:<remote-path>. |
DEST | yes | Destination path — local, or <target>:<remote-path>. |
Exactly one of SOURCE/DEST must be a remote. Either both sides parsed as targets or neither did. Check the label against pks ssh list, and confirm the remote side is written as label:/path.
A Windows path like C:\build was treated as local. That is correct. A target prefix needs at least two characters before the colon, so single-letter drive prefixes are never mistaken for a label.
The transfer fails on a directory. Add -r.
Permission denied with no prompt. BatchMode=yes prevents interactive fallback. Load the key into your agent, or bind the target to a pks-held key — see pks ssh key.
A custom port seems ignored. copy passes the port with scp's uppercase -P, taken from the registry entry. Re-register with --port if the stored value is wrong.