Encrypt a copy of your file to another machine in one command.
You have a file on one box and you need it on another — and you want it encrypted in transit, not pasted through a chat log. scp is the shortest answer in Unix, and people misuse its flag order so often the confusion has a name.
scp (secure copy) copies files or directories between hosts using SSH for transport and encryption. The syntax follows cp but one side is a remote path written as [user@]host:/path. `scp file.txt me@server:/tmp/` pushes the file over the encrypted SSH channel to /tmp/ on server. Reverse the argument order and it pulls instead. Because it rides on SSH, you get integrity checking, compression, public-key auth, and agent forwarding for free — and zero server setup beyond an SSH daemon you probably already run.
When you are knee-deep in a deployed app, moving an artifact between machines is a daily event: ship a build to prod, pull a log for inspection, drop a config onto a box. scp does it with one command and the encryption is non-negotiable — the data never crosses the wire in plaintext. It is simpler than rsync for one-off pushes (no flag soup), and once it clicks you stop scp-ing like a beginner, which is honestly rare: most people get the source/destination order wrong on the first try and it bites them silently.
scp build.tar.gz deploy@web-01:/var/www/releases/
build.tar.gz 100% 128MB 45.6MB/s 00:03
Push build.tar.gz from the local box to /var/www/releases/ on web-01 over SSH. The progress line is printed to stderr; the transfer is encrypted end to end.
scp -r ./dist app@staging:/srv/app/
public.css 100% 12KB 8.2MB/s 00:00 index.html 100% 18KB 11.9MB/s 00:00 main.js 100% 342KB 22.1MB/s 00:00 assets/logo.png 100% 45KB 15.3MB/s 00:00
-r recursively copies the whole ./dist directory tree to /srv/app/ on staging. Without -r, scp refuses to copy a directory.
scp db@db-01:/var/log/mysql/error.log .
error.log 100% 26KB 14.9MB/s 00:00
Reverse the arguments and scp pulls the file from db-01 down to the current directory. The remote path comes first now — a common source of confusion.
scp -P 2222 -C config.toml deploy@bastion:/etc/app/
config.toml 100% 38KB 18.3MB/s 00:00
-P sets a non-default SSH port (2222 here) and -C enables compression, handy for slow links and text-heavy config files.
| Flag | Meaning |
|---|---|
-r | recursively copy an entire directory tree |
-P <port> | SSH port to connect to on the remote host (capital P, unlike ssh) |
-p | preserve modification times, access times and file mode bits |
-C | enable compression on the transfer (passes -C to ssh) |
-i <identity_file> | use a specific private key for public-key auth |
-l <limit> | limit bandwidth used by the transfer, e.g. -l 800 to cap at 100 KB/s |
-q | quiet mode — suppress the progress meter and warnings |
scp shipped with OpenSSH in 1999 (OpenSSH 1.2), written by Theo de Raadt and colleagues as a secure replacement for the unencrypted rcp. It copied rcp's interface so users could switch without relearning anything, but tunneled the data over the SSH-protocol, giving it encryption and integrity checks. It became the default way to move files between Unix machines for a decade and is still everywhere.
Because the original scp predates SSH's SFTP protocol and uses the original SCP protocol, OpenSSH 9.0 (2022) switched scp to use SFTP by default for better security, and added a -O flag to force the old mode for ancient servers. The flag quirks survive too: the port is -P (capital) in scp but -p (lowercase) in ssh — a trap that has burned everyone at least once.