scp
Securely copy files to/from a remote host over SSH
By CMD Script Team · 4 min read · Last updated
scp [OPTIONS] SOURCE... DESTINATIONOptions
| Flag | Description |
|---|---|
-r | Recursively copy entire directories |
-P | Connect to a non-default remote port (uppercase, unlike ssh's -p) |
-i | Use a specific identity (private key) file for authentication |
-p | Preserve modification times, access times, and modes from the source |
-C | Compress data during transfer |
-v | Verbose mode, useful for debugging connection problems |
-l | Limit bandwidth used, in Kbit/s |
Distribution compatibility
- Ubuntu
- Debian
- Fedora
- Arch
- macOS
What it does
scp (secure copy) copies files and directories between hosts over an encrypted SSH
connection, using the same authentication (passwords, keys, agents) as ssh. It's the
go-to one-shot command when you just need to move a file or directory to or from a
remote machine without opening an interactive session — unlike sftp, there's no
prompt to navigate, you specify source and destination and it copies immediately.
Beginner examples
scp file.txt user@host:/home/user/— copy a local file to a remote directoryscp user@host:/etc/hostname ./hostname-backup— copy a remote file to the local machinescp -r ./project user@host:/tmp/project— recursively copy a local directory to a remote hostscp file1.txt file2.txt user@host:/tmp/— copy multiple local files in one command
scp notes.txt user@server.example.com:/home/user/notes.txt
Advanced examples
- Copy on a non-default SSH port:
scp -P 2222 file.txt user@server.example.com:/tmp/ - Preserve timestamps and permissions during the copy:
scp -p config.yml user@host:/etc/app/config.yml - Copy directly between two remote hosts (traffic flows host-to-host, not through your
machine):
scp user1@hostA:/data/report.csv user2@hostB:/backup/ - Force the copy through your local machine when direct host-to-host isn't possible:
scp -3 user1@hostA:/data/report.csv user2@hostB:/backup/ - Copy a wildcard set of remote files down to the local machine:
scp 'user@host:/var/log/*.log' ./logs/
scp -r -P 2200 -i ~/.ssh/deploy_key ./dist deploy@server.example.com:/var/www/app
Common mistakes
- Forgetting to quote wildcard remote paths (
user@host:/var/log/*.log) — without quotes, the local shell tries to expand the glob against the local filesystem before scp ever sees it. - Omitting
-rwhen copying a directory and getting a "not a regular file" error. - Confusing
-p(preserve attributes) with-P(port) — using the wrong case either connects to the wrong port or silently does nothing useful. - Assuming scp merges into an existing remote directory the way
cpdoes locally — trailing slashes and existing-directory checks behave slightly differently than localcp, so always double check the destination path.
Tips
- Use
-Cto enable compression, which helps a lot when copying large, compressible files (like text logs or source trees) over a slow link. - Add
-vwhen a transfer silently fails or hangs — it shows the SSH negotiation steps and usually reveals the real problem (wrong key, wrong port, host key mismatch). - For repeated or partial transfers (resuming, only-changed-files), reach for
rsync -e sshinstead — scp always re-copies the whole file every time.
Best practices
- Prefer key-based authentication with
ssh-agentover typing passwords, especially in scripts or CI pipelines that call scp non-interactively. - Use
-rdeliberately and check what you're copying — recursive copies can pull in far more than intended if a directory contains build artifacts,.git, ornode_modules. - For anything beyond an occasional one-off copy, prefer
rsync— it avoids re-transferring unchanged data and handles interrupted transfers far more gracefully.
Try it yourself
A simulated shell with a sample home directory — experiment freely, nothing leaves your browser. Type help to list supported commands.
Real-world use cases
- Pulling a log file off a production server for local debugging:
scp prod:/var/log/app/error.log ./. - Deploying a built frontend bundle to a web server:
scp -r ./dist deploy@web1:/var/www/app. - Grabbing a database backup dump from a remote host before restoring it locally.
Common interview questions
- How does scp differ from sftp? scp is a single, non-interactive copy command (source and destination given up front); sftp opens an interactive session for browsing and transferring files. Both run over SSH.
- Why does scp use -P for the port while ssh uses -p? Because scp already used
lowercase
-pto mean "preserve file attributes" (mirroringcp -p), so the port flag had to be uppercase to avoid a collision. - How would you copy a file between two remote servers without downloading it
locally first?
scp user1@hostA:/path/file user2@hostB:/path/, run from a machine that can reach both hosts (data flows directly between them unless-3is used to route it through the local machine).
Frequently Asked Questions
How do I copy a file to a remote server with scp?
scp localfile.txt user@remote-host:/path/on/remote/ — scp uses the familiar cp-like SOURCE DESTINATION syntax but with host:path for anything remote.
Why does scp use -P for port but ssh uses -p?
Historical inconsistency: scp reserved lowercase -p for 'preserve file attributes' (matching cp -p), so it had to use uppercase -P for the port, unlike ssh which uses lowercase -p for the port.
Is scp deprecated?
OpenSSH has deprecated the legacy scp protocol in favor of using SFTP under the hood for transfers, but the scp command itself is still shipped and widely used; newer OpenSSH versions transparently use SFTP unless you force the old protocol.
How do I copy between two remote hosts?
scp user1@hostA:/path/file user2@hostB:/path/ copies directly between two remote machines when run from a third host that can reach both (add -3 to route the data through the local machine if direct host-to-host connectivity isn't available).
Cheat sheet
Download a quick-reference cheat sheet for scp.