Introduce a new CLI flag --no-print-skip to hide SKIP status lines during sync/delete operations while preserving existing skip behavior and summary counters. Update help output, README, and AGENTS.md to document the new option.
SFTPsync
Small PHP CLI utility to synchronize directories and manage files on a remote server over SFTP.
What It Does
- Sync local directory to remote (
--sync) - Sync remote directory to local (
--sync-down) - Delete one remote file (
--delete) - Delete remote directory recursively (
--delete-dir) - Combine multiple actions in one run (executed in CLI order)
- Skip selected paths during sync or delete using repeatable rules
Requirements
- PHP 8+ (CLI)
- PHP
ssh2extension enabled (ssh2_connect,ssh2_sftp, ...) - Network access from your machine to the target SFTP host
Quick Start
From repository root:
php src/SFTPsync.php --host example.com --user myuser --password mypass --sync ./local /var/www/app
If --host, --user, or --password is missing, the script asks for it interactively (TTY only).
CLI Usage
php src/SFTPsync.php --host <host> --user <user> --password <password> [--port <port>] <actions...>
Actions (repeatable)
--sync <local_dir> <remote_dir>: upload local changes to remote--sync-down <remote_dir> <local_dir>: download remote changes to local--delete <remote_file>: delete one remote file--delete-dir <remote_dir>: delete remote directory recursively (with safety checks)
Options
--host <host>: required (or prompted)--user <user>: required (or prompted)--password <password>: required (or prompted)--port <port>: optional, default22--print-relative: show paths relative to action root in logs--no-print-skip: suppressSKIPstatus lines during execution--skip <file_or_dir>: repeatable, applied to--syncand--sync-down--skip-delete <file_or_dir>: repeatable, applied to--deleteand--delete-dir-h,--help: show help
Examples
# Upload local -> remote
php src/SFTPsync.php --host example.com --user u --password p --sync ./app /srv/app
# Download remote -> local
php src/SFTPsync.php --host example.com --user u --password p --sync-down /srv/backups ./backups
# Multiple actions in one run (executed left-to-right)
php src/SFTPsync.php --host example.com --user u --password p \
--sync ./a /remote/a \
--delete /remote/a/old.zip \
--sync-down /remote/logs ./logs
# Skip selected entries during sync
php src/SFTPsync.php --host example.com --user u --password p \
--skip .git --skip node_modules --skip cache/tmp \
--sync ./app /srv/app
# Delete remote directory but keep selected subpaths
php src/SFTPsync.php --host example.com --user u --password p \
--skip-delete .well-known --skip-delete uploads/keep \
--delete-dir /srv/app
Sync Behavior
For each file pair, transfer happens when:
- target file does not exist, or
- file size differs, or
- source mtime is newer than target mtime
After upload/download, mtime is propagated to the target when possible.
Skip Rule Matching
- Rule without slash (example:
node_modules) matches any path segment with that name. - Rule with slash (example:
cache/tmp) matches that subpath within a relative path. - Rules are normalized to forward slashes.
Safety Notes
--delete-dirrefuses dangerous roots such as empty path,/,.,.., and similar dot paths.- Delete operations run only on the remote side.
- Path handling normalizes slashes and trims duplicate separators.
Exit Codes
0success1runtime/SFTP error2invalid CLI arguments
Output
The script prints status lines (MKDIR, UPLOAD, DOWNLOAD, DELETE, RMDIR, SKIP, ERROR) and a final summary with operation counters.
Use --no-print-skip if you want to keep skipped-item accounting in the final summary but hide individual SKIP log lines during the run.
Languages
PHP
100%