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

syq cp

Copy files, directories, and symlinks locally, over SSH, or with S3. See Copy files for examples and remote and S3 copy details.

syq cp --srcs-in project --to server --into backup --dry-run -v

Put source selectors and --mapping before --to or a placement option. For scripting, see environment variables and results.

syq cp [OPTIONS] SOURCE... [PLACEMENT]
syq cp [OPTIONS] --src-fd FD --as PATH
syq cp [OPTIONS] SOURCE --as-fd FD

Sources and filtering

Argument / optionMeaning
--src-fd <FD>Read raw bytes from an inherited local descriptor (0 for stdin), instead of a source path
--from <ENDPOINT>Source endpoint ([USER@]HOST[:PORT] or s3://BUCKET); omitted means local
-C, --cwd <DIR>Resolve relative source selectors from DIR
--root <DIR>Resolve source selectors beneath DIR and refuse any escape
--src <PATH>Select a named source object; attach =PATH when it begins with - (repeatable)
--srcs-in <DIR>Select a directory’s contents; attach =DIR when it begins with - (repeatable)
--src-non-dir <PATH>Select a named non-directory source object; attach =PATH when it begins with - (repeatable)
--src-dir <DIR>Select a named source directory; attach =DIR when it begins with - (repeatable)
--src-non-dirs <PATH>...Select several named non-directory source objects
--src-dirs <DIR>...Select several named source directories
--srcs <PATH>...Select several named source objects
--ignore <PATTERN>Skip paths matching a gitignore-style pattern (repeatable)
--ignore-from <FILE>Securely open and read gitignore-style patterns from raw-byte FILE (repeatable; stacks in command-line order)
[PATH]...Named source objects (shorthand for –src)

Destination and mapping

Argument / optionMeaning
--as-fd <FD>Write raw bytes to an inherited local descriptor (1 for stdout), instead of a destination path
--to <ENDPOINT>Destination SSH endpoint, @NAME, or s3://BUCKET; placement defaults to –into
--into <DIR>Put selected names inside DIR, creating it if necessary
--into-new <DIR>Put selected names inside DIR, which must not exist
--into-existing <DIR>Put selected names inside an existing directory
--as <PATH>Map one named source exactly to PATH; never follow its final entry
--as-new <PATH>Map one named source exactly to PATH; its final entry must not exist and is never followed
--as-existing <PATH>Map one named source exactly to PATH; its final entry must exist and is never followed
--mapping <FILE>Copy the entries of a local NDJSON mapping manifest (- reads stdin), acquired before destination changes, instead of selecting sources; entry src paths are relative to -C and dst paths are relative to the –into container

Updates and deletion

Argument / optionMeaning
--only-newCopy entries found missing; keep metadata of entries found present; adding children requires write access
--inplaceUpdate destination files directly, using no full-sized staging file; interruption can leave them incomplete
--pruneAfter copying, remove target-only objects in mapped directory scopes; ignored source paths remain protected
--max-delete <N>With –prune, refuse all removals if more than N are planned
Argument / optionMeaning
--followFollow symlinks in all directly supplied filesystem paths
--follow-srcFollow symlinks in directly supplied source paths
--follow-dstFollow symlinks in directly supplied destination paths
--preserve <FEATURE>Preserve times, permissions or ownership, or copy special files (repeatable/comma-separated)

Possible values:
- times: Preserve modification times (already the default for named destinations)
- permissions: Preserve permission bits
- ownership: Preserve owner and group IDs
- specials: Copy device nodes and special files

Verification

Argument / optionMeaning
--hashHash existing source and destination files instead of trusting size and modification time
--integrity-checking <KEY=VALUE,...>Payload checks

Connections and remote execution

Argument / optionMeaning
--no-compressDisable transport compression
--receiver-max-entries <N>Command-restricted receiver ceiling: refuse to touch more than N destination entries
--receiver-max-bytes <SIZE>Command-restricted receiver ceiling: refuse to write more than SIZE bytes of file data in total
--receiver-receipt <DETAIL>Command-restricted receiver receipt detail: final sizes (default) or also final BLAKE3 file hashes

Possible values:
- sizes: Final type and size of every path the transfer could have changed
- hashes: Sizes plus a closure-time BLAKE3 hash of every regular file
--auth-from <auto|ssh|@NAME>Authorize through @NAME (also S3 copies), or use local SSH access (default: auto)
--coordinate-at <COORDINATE_AT>Choose the endpoint that runs the coordinator

Possible values:
- auto: Run locally unless both endpoints are remote, then run at the source
- src: Run the coordinator at the source endpoint
- dst: Run the coordinator at the destination endpoint
- local: Keep the coordinator on the invoking machine and relay the data there

[default: auto]
--rsh <COMMAND>Remote shell command (default: ssh); the command owns SSH and agent policy when set
--syq-path <PATH>Use this remote syq executable instead of installing a helper
--no-bootstrapUse syq on the remote PATH instead of installing a helper
--tcp-plainUse TCP data connections without encryption (trusted networks only)
--no-tcpSend file data through SSH rather than separate TCP data connections
--tcp-ports <LO-HI>Port range remote listeners use for TCP data connections

[default: 47600-47699]
--tcp-congestion <ALGO>Use this congestion-control algorithm for TCP data sockets (Linux only)
--detachRun at the remote coordinator and return after launch; requires –peer-auth own-credentials or –rsh
--peer-auth <MODE>How the coordinator authenticates to the peer (see the values below); –rsh takes over this policy entirely

Possible values:
- restricted: Constrained agent broker plus the command-restricted receiver on the peer
- broker: Constrained agent broker only; the peer runs no command-restricted receiver
- own-credentials: Forward nothing; the coordinator must hold its own credentials for the peer
- full-agent: Expose the complete local SSH agent to the coordinator, as ssh -A would

[default: restricted]
--pscope <PATH>Use an ephemeral SSH persistence scope created by syq persist on --ephemeral

S3 connection settings

Argument / optionMeaning
--s3-endpoint <URL>S3 API endpoint URL (also AWS_ENDPOINT_URL_S3 or AWS_ENDPOINT_URL)
--s3-region <REGION>S3 signing region, used as given (otherwise syq asks AWS where the bucket is)
--s3-profile <NAME>AWS shared configuration/credentials profile
--s3-header <NAME: VALUE>Add a header before signing every S3 request (repeatable; S3-to-S3 metadata/tag overrides are refused)

Performance and resource limits

Argument / optionMeaning
--performance-tuning <KEY=VALUE,...>Workers, request sizes, and copy methods
--resource-limits <KEY=VALUE,...>Bandwidth and concurrency ceilings

Preview, progress, and results

Argument / optionMeaning
--results <FILE>Write the machine-readable NDJSON result stream to FILE (created fresh; an existing file is refused)
--results-fd <FD>Write the result stream to an inherited file descriptor the caller opened (e.g. --results-fd 3 3>run.ndjson); must be above 2
-n, --dry-runPreview without changing copy/removal data; remote setup may still cache the helper or install syq; requested results files are still written
-v, --verbose...List files with -v; explain helpers and transport with -vv
-q, --quietSuppress non-error messages
--progressShow progress even when stderr is not a terminal
--no-progressNever show the human progress display
--statsPrint transfer statistics, worker waits, endpoint operations and CPU at the end

Help and version

Argument / optionMeaning
-h, --helpShow common usage and options
-V, --versionPrint version
--help-allShow all options and details

Update policies

--into-existing requires the destination directory to exist but allows new files inside it. --only-new can add children to an existing directory, but does not change that directory’s permissions to make it writable.

--only-new cannot combine with --inplace: an interrupted write could leave a file that a retry skips. Restricted receivers also reject --as-new --inplace, because direct writes do not enforce that destination condition. S3 and named receiving destinations do not support --inplace; see Copy limits.

These policies do not disable requested pruning. Descriptor-specific restrictions are listed under file descriptors.

Pruning

--prune deletes only within the copied directories, after copying succeeds. Ignored paths, syq partial files, and recovery entries are kept. This also keeps their parent directories; extra hard links to copied files may be kept too. An interruption during deletion can leave some extras already removed.

Keep the source outside the destination. Syq detects overlap locally and for remote paths using the same host name, user, and port. Different SSH aliases or shared storage can hide overlap from this check. Wait for other copies into the destination to finish before pruning, so their new files are not deleted as extras.

Filename and type conflicts

If the source has both Report.txt and report.txt, a case-insensitive destination cannot store both. Syq does not check for that before copying, and one file can replace the other. The same problem applies to distinct Unicode spellings that the destination treats as one name. Rename the source entries or use a destination that can distinguish them. Unsupported names are reported as copy errors.

Syq refuses replacements between directories and non-directories, including empty directories. Move or remove the conflicting destination before retrying. Other replacements can fail if the filesystem lacks the operation needed to replace an entry safely; the old entry is kept.

Capacity checks

For missing or empty filesystem destinations, syq checks available bytes and capacity for new files when the filesystem reports them. A clear shortage fails before copying. Updates to populated destinations do not use this whole-copy estimate: existing data may be reused or replaced. Allocation errors still fail the affected copy.

Metadata details

Source setuid, setgid, and sticky bits are not copied without --preserve=permissions. Ownership uses numeric IDs. On macOS, an existing destination directory must be readable before syq can temporarily repair missing write or search permission.

Modification times are preserved for named file destinations. Output descriptors require explicit --preserve=times; see below.

File descriptors

--src-fd 0 reads stdin; --as-fd 1 writes stdout. Use them to connect local, SSH, or S3 copies to other programs; see Shell pipelines and file descriptors. Bash process substitution also works with ordinary source syntax:

syq cp --src <(gzip -c data) --to server --as data.gz

Paths such as /dev/fd/63 refer to descriptors in the local syq process.

Each stream copy takes one source. Stdin and process substitution have no filename, so use --as to choose one, or --as-fd to write to a descriptor. A named pipe can use --into: syq cp incoming.fifo --into saved waits for a writer, then saves its bytes as the regular file saved/incoming.fifo. A symlink to a pipe requires --follow-src. Selecting a pipe alongside other sources, including through a shell glob, is an error. Directory copies never read pipes; --preserve=specials copies the pipe itself.

Completion and failures

A named destination is replaced only after the transfer succeeds. The -new and -existing placement conditions apply as usual, before a named pipe is opened. S3 new-object writes also refuse replacement if an object appears during the upload.

If the producer fails halfway through, syq can still successfully save the bytes it received: EOF does not tell it whether the producer succeeded. Bash’s set -o pipefail detects failures in a pipeline but cannot undo a file already saved. Process substitution needs a separate check of the producer’s status. In Python, managed streams let you commit only after your producer succeeds.

An output descriptor may contain incomplete data after a failure. Check syq’s exit status before using the result. A consumer closing early makes syq fail. Forced termination can leave a .syq-stream-* temporary file beside the destination.

Options and file behavior

Progress, --stats, and -v go to stderr, leaving stdout for payload. Statistics report bytes, elapsed time, and average rate; pipe lengths are unknown until EOF. Use --resource-limits bandwidth=RATE to limit throughput.

--only-new skips a destination that exists. Existing directories, S3 key prefixes, and dangling symlinks also count as existing for --only-new. Skips succeed without reading input or opening a named FIFO. A shell producer can therefore receive SIGPIPE; in Python, check the writer’s skipped property before producing bytes. An output FD already exists, so --only-new --as-fd N always skips after validating the source.

Use --dry-run to check source and destination placement without reading input, opening a named pipe, or changing the destination. It cannot check a payload hash or predict the length of a pipe. --results and --results-fd report stream_result records separately from payload; results and payload/completion descriptors must differ.

Transport and limits

Filesystem streams use parallel data workers over SSH or encrypted TCP, with automatic worker tuning as in regular-file copies. They accept workers, request-size, pipeline-depth, and bw-pacing tuning; workers=N fixes the worker count, and --no-tcp keeps data on SSH. S3 transfers one object using multipart controls; see Descriptor copies.

Restart recovery, named receiving destinations, detached execution, directory selection, and content comparison are unsupported.

Descriptor offsets and metadata

Other inherited descriptors work too, except 2, which is reserved for diagnostics. Dedicate each descriptor to the copy. Syq advances its offset, respects append mode, and leaves its blocking mode alone; it does not truncate it. A literal - is a filename.

When a regular file is copied to a named destination, syq preserves its modification time. New named files use the source permissions limited by the destination umask; existing files keep their permissions. S3 uploads store file attributes in object metadata.

Output descriptors use the timestamps from normal writes, including when appending to an existing file. Add --preserve=times to copy the source modification time instead; this changes the whole destination file’s timestamp even for a partial write. --preserve=permissions,ownership copies those attributes without changing timestamps. S3 downloads interpret object metadata when attributes are requested; time preservation uses S3’s modification time if no syq attributes are stored.

Input pipes, sockets, and devices have no payload metadata, so they reject --preserve. Their new named destinations use 0666 limited by the umask and the time of the write; existing files keep their permissions. Output pipes likewise cannot preserve times, permissions, or ownership. Parent directories are created as needed. The source --cwd / --root options apply to pathname sources. --root with --src-fd is rejected because it cannot confine a descriptor that is already open. Symlink handling is unchanged; see Symlinks. Named remote sources must be regular files.