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

Copy files

syq cp project --into backup

This copies project to backup/project. Existing files are updated when needed; unrelated files stay.

The default final summary reports transferred files and bytes, unchanged files and bytes, directories created, elapsed time, rate, and any errors.

Add -v to list copied paths. -vv also explains helper selection and transport; --stats adds scan totals, excluded-file counts, connection count, and available TCP statistics. For example:

syq cp -vv --stats project --into backup

See diagnosing a slow copy for interpreting transport and performance details.

See where files go

A named directory brings its name along. --srcs-in copies its contents; --as chooses an exact destination name.

syq cp project --to server --into /backup

Copies project into /backup/project on server. Existing files outside that directory stay.

Each example starts from the same files shown under Before.

Your machine

project/
├── index.html
└── images/
    └── logo.svg

Server · Before

/backup/
├── index.html (old)
└── notes.txt

Server · After

/backup/
├── index.html (kept)
├── notes.txt (kept)
└── project/ (new)
    ├── index.html
    └── images/
        └── logo.svg

Note to rsync users: trailing slashes have no special significance in syq’s native commands. syq rsync keeps rsync’s slash rules.

Copy over the network

Use --to to send files, or --from to fetch them:

# Copy project to /backup/project on server.
syq cp project --to server --into /backup

# Fetch /data/a and /data/b from server into ./data/a and ./data/b here.
syq cp --from server -C /data --src a --src b --into ./data

-C DIR is shorthand for --cwd DIR: look for the source files in DIR. In the second example, /data is on the server and ./data is on your machine.

To use the default destination:

syq cp project --to server       # put project in your home directory on server
syq cp --from server project     # fetch project into your current directory

Endpoints use [USER@]HOST[:PORT], for example alice@server:2222. Host names cannot start with a dash, including when using an --rsh wrapper. Enclose IPv6 addresses in brackets: alice@[2001:db8::1]:2222. A colon in a native path is simply part of the path.

For two remote endpoints, see Copy between servers. To send files to your laptop from a server shell, see Send files home from a server.

Progress

Syq shows a progress bar when running in a terminal. It tracks bytes processed; while files are still being discovered, the percentage is unknown. Wider terminals also show elapsed time, speed, ETA, and file counts.

Use --progress to force the display or --no-progress to hide it. --quiet hides it too. After five seconds without a byte update, no update shows how long it has been; this does not by itself mean the connection has failed. Wait for the final summary to confirm success, even if the byte bar looks full.

The bar also covers syq rm, counting entries instead of bytes. --progress-json provides JSON progress for displays; use results records to track completion in scripts.

Choose a destination

OptionMeaning
--into DIRPut the selected names inside DIR
--as PATHCopy one named source to exactly PATH
--into-new DIR, --as-new PATHAlso require the destination not to exist
--into-existing DIR, --as-existing PATHAlso require it to exist
# Copy report.txt under a new name; refuse to overwrite an existing entry.
syq cp report.txt --as-new reports/final.txt

--into uses or creates a directory. --as can rename a directory too. Sources that would collide at one destination are refused before copying.

Choose which existing files to update

By default, selected destination entries are updated when needed. These options apply to individual entries inside the copy:

OptionBehavior
--only-newCopy entries found missing; keep entries found present and their metadata
--only-existingUpdate existing entries; create no missing entries or directories
--skip-newerSkip regular files whose destination modification time is newer
# Import new files without replacing existing files.
syq cp --only-new --srcs-in incoming --into archive

# Refresh only files already in the destination.
syq cp --only-existing --srcs-in project --into deployed

--only-new keeps existing entries and their metadata, while adding missing children to existing directories. Those directories must be writable; syq does not change their permissions to add files. Adding children can still change directory timestamps. A dry run does not test write access.

If a source directory meets an existing non-directory, --only-new skips that subtree. --only-existing skips a subtree when its destination is missing or is not a directory. It cannot combine with --into-new or --as-new. The placement options --into-existing and --as-existing check only the placement path, rather than every copied entry.

--skip-newer compares timestamps, not the age of the contents. It affects only regular-file pairs; replacing a different entry type still occurs. Combine it with --only-existing to avoid creating missing entries too.

--only-new cannot combine with either policy. Neither --only-new nor --skip-newer can combine with --inplace: an interrupted write could leave an incomplete file that the next run skips. Restricted receivers also refuse --only-existing --inplace.

These options do not disable --prune; requested pruning still removes extras.

Preview changes

--dry-run previews a copy without changing the destination. On its own it prints a summary; combine it with -v to list the planned changes by path:

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

The summary shows where files would land, what would change, and how much data may move. Copy data stays unchanged; a requested results file is still written. The filesystem can change between preview and execution.

Mirror a directory

--prune removes destination files that have no counterpart in the source:

syq cp --prune --max-delete 100 --srcs-in build --into-existing deploy

This updates deploy from build, then removes extras. Preview with --dry-run -v first. If more than 100 removals are planned, none are performed and the command exits 25.

Pruning stays inside the copied directories. Copying named directories a and b into backup prunes backup/a and backup/b, leaving backup/c alone. Ignored paths and files skipped by size limits are protected.

Scan errors prevent deletion. An interruption after deletion starts can leave some extras removed. Do not prune while another copy is writing into the same tree: its completed files can be treated as extras. Recognized partial files and directories containing them are protected from pruning. With -v, syq lists each extra file it keeps because its name matches the partial-file format.

Ignoring paths

# Use the project's existing ignore rules.
syq cp --ignore-from .gitignore --srcs-in project --into backup

# Skip node_modules and object files.
syq cp --ignore node_modules --ignore '*.o' --srcs-in project --into backup

Patterns use gitignore syntax. Rules run in command-line order; the last match wins. ! re-includes a path.

PatternMatches
fooA file or directory named foo at any depth
/foofoo at the source root
foo/Directories named foo
*Within one path component
**Across path components

Ignored directories are not scanned. To keep part of one, include the parent:

# Skip other logs, but copy logs/keep and its contents.
syq cp --ignore 'logs/*' --ignore '!logs/keep/' --srcs-in project --into backup

Ignored paths are also protected from pruning.

Resume an interrupted copy

Rerun the command. Completed files are skipped; partially copied files can reuse matching blocks. Each run writes its own fresh partial beside the destination and replaces the final file only when complete. When resuming, syq can copy bytes from a previous partial or the existing destination into its own output, hash the bytes it copied, and transfer blocks that differ from the source before publishing. The previous partial stays unchanged. Reuse is best effort; local direct copies can be faster than looking for reusable blocks and take priority.

Resuming requires space for the new output as well as the previous partial. This can require enough free space for another complete file, even when only a small amount remains to transfer.

Concurrent copies use separate partials. With unchanged sources, each completed file comes from one copy; different copies may win for different files. This does not make a whole tree a snapshot. --inplace still exposes unfinished updates, and pruning can delete another copy’s completed files.

Partials are named .FILENAME.syq-tmp.RANDOM, with 16 random characters at the end. The filename portion is shortened or omitted when space is tight. Syq removes its own partial when it publishes the completed file. Interrupted runs can leave partials behind, including after a later successful retry. Partials with shortened or omitted filenames may not be reused.

To remove leftover partials, stop copies writing into the tree, then preview and run:

syq clean-partials --dry-run -v backup
syq clean-partials backup
# Search several remote trees with the parallel removal workers.
syq clean-partials --on server --cwd /data -j 8 backup archive

This command removes regular files with the current partial-name format. It keeps directories, other filenames, and symlinks, and does not follow symlinks. Use --root DIR to confine traversal and --results FILE for removal results. The results use the same mode: "rm" records as syq rm; they do not distinguish a partial sweep from other removal commands. A regular file deliberately named like a partial is also selected. Old partial formats are neither reused nor selected by this command; remove those manually.

Check file contents

Syq normally skips files whose size and modification time match. --hash checks contents even when those two attributes match:

syq cp --hash --srcs-in project --into backup

This changes how syq decides what needs copying. For larger network copies, syq still compares blocks when size or modification time differs, even without --hash, so it can reuse unchanged data. Local and small copies may use faster paths instead.

Transferred data is always checked for corruption. For files being changed by another program, stop the writer or copy a snapshot. No copy makes the whole tree transactional or guarantees durability across power loss.

To compare without writing, use --verify-only:

syq cp --verify-only --srcs-in project --into backup

This compares file contents, symlink targets, and entry types without writing. Missing or different entries make the command fail. It does not compare metadata or look for extra destination files.

For two servers, add --coordinate-at local to compare through your machine using ordinary SSH access, with no restricted receiver enrollment. This also supports --results. See remote verification.

In-place writes

By default, syq builds an updated file beside the old one and replaces it when complete. --inplace writes directly into the destination file instead:

syq cp --inplace large-file --to server --into /backup

This saves temporary disk space and can avoid copying unchanged data into a new file. Readers can see a mixture of old and new contents during the copy. If interrupted, the incomplete file stays at its final name until you finish the copy. Writes through a hard link also affect its other names.

Use the default when other programs need to read a complete file throughout an update. Copies sent back to your laptop do not support --inplace.

Preserve metadata

Copy keeps modification times and copies symlinks as symlinks. New files use the source read, write, and execute permissions limited by the destination umask; existing files keep their destination permissions. For example, a new script with mode 755 stays executable with umask 022. Source setuid, setgid, and sticky bits are not copied by default.

To copy source permissions exactly, including onto existing files, or request ownership too:

syq cp --preserve=permissions,ownership project --into backup

permissions preserves modes; ownership requests numeric owner and group; specials enables device, FIFO, and socket nodes. Ownership needs suitable permissions on the destination. Hard links, ACLs, and xattrs are not preserved.

A named symlink is copied as a link. Syq refuses to follow links in paths you supply unless you ask it to:

OptionFollow links in
--follow-srcSource paths
--follow-dstDestination paths
--followBoth, plus files named by options such as --ignore-from
# Copy the directory current-project points to as backup/current-project.
syq cp --follow-src current-project --into backup

With --as link, the final link itself is replaced, even with --follow-dst. Links found inside a directory are never followed. See the security explanation.

Keep sources inside a directory

--root DIR both sets the source directory and prevents selections from escaping it:

# Copy /srv/data/reports and /srv/data/photos into backup.
syq cp --root /srv/data reports photos --into backup

Sources must be relative to that root. A selection such as ../private is refused; even with --follow-src, symlinks cannot lead outside the root. Unlike -C, this is a boundary, not just a starting directory. It does not constrain the destination.

Output and diagnostics

Human output, including persist status and persist receive status, escapes terminal control characters, Unicode line separators, and directional marks in names and peer diagnostics. JSON status output keeps the original values.

More options

--src-non-dir and --src-dir require a non-directory or directory respectively. Use --min-size and --max-size to select regular files by size.

For parallelism and bandwidth controls, see Speed. For scripts, see Automation results.

Use --help (or -h) for everyday options and --help-all for the full list, including tuning, scripting, and manual setup. syq help COMMAND shows the same help without running the command. In syq rsync, -h means human-readable sizes; use --help for help.