Copy Files Securely with scp

Learn to copy files securely with scp in this Linux networking telemetry tutorial — hands-on steps, troubleshooting, and next lesson.

Focus: copy files securely with scp

Sponsored

You've SSH'd into a remote box, debugged a service, and now you need to move a log file or a config backup back to your laptop. Dragging files over a chat app or firing up a web server on the remote host feels wrong — it's slow, insecure, and fragile. This lesson teaches you to copy files securely with scp, the OpenSSH tool that piggybacks on the SSH encryption you already trust, so you can transfer files between machines with the same security and simplicity as an SSH connection.

The Problem: Moving Files Between Hosts

The pain point is real: you've got a file on a remote server, but you need it locally — or the other way around. Classic approaches are painful:

  • FTP: plaintext credentials and data — a security disaster.
  • HTTP: needs a running web server, exposes files to anyone who knows the URL, and doesn't authenticate by default.
  • Copy-paste through a terminal: breaks binary files, corrupts large files, and is absurdly slow.
  • Cloud storage: adds third-party latency, storage costs, and is overkill for a quick config transfer.

None of these are good for a developer who already lives in the terminal. The solution is scp — a tool built on SSH that gives you secure, authenticated, and encrypted file transfer without any extra setup.

Core Concept / Mental Model

Think of scp as cp over SSH. The cp command copies a file from one location to another on the same machine. scp extends that to a remote machine, using the same SSH handshake that you use to log in. The file's contents are encrypted in transit, and the remote server authenticates your identity before allowing the transfer.

Here's the mental model in words:

  • Source and destination are defined using the same syntax as SSH: user@host:path.
  • If you omit user@, scp uses your current local username.
  • If you omit the host, you're copying locally (like cp).
  • The command uses the SSH protocol on port 22 by default, and can be configured with keys or passwords exactly like SSH.

One key difference from cp: the -r flag is required to copy directories, and scp doesn't merge or overwrite by default — it will overwrite existing files, but only if you have permission.

How It Works Step by Step

When you run an scp command, several things happen under the hood:

  1. Connection establishment: scp opens an SSH connection to the remote host, using your configured port, identity key, or password.
  2. Authentication: The server verifies your identity — either with a password or a public key — exactly as if you logged in via SSH.
  3. File transfer: The client and server negotiate an encryption algorithm and transfer the file through an encrypted channel.
  4. Copy semantics: The remote scp server (usually the SSH daemon) reads or writes the file on the remote filesystem, respecting permissions and ownership.
  5. Progress tracking: By default, scp shows a progress bar, transfer rate, and time remaining.

The key point: security comes from SSH. You get the same encryption, host key verification, and authentication that you rely on for every other SSH operation.

Hands-on Walkthrough

Let's start with the basics. Open a terminal (locally, on your own machine) and run these examples to get a feel for scp.

Example 1: Copy a local file to a remote host

# Copy 'app.log' from your local machine to the home directory of user 'dev' on 'example.com'
scp app.log dev@example.com:/home/dev/

Expected output (you'll see an SSH banner and then a progress bar):

app.log              100%  123KB  12.3KB/s   00:10

Example 2: Copy a remote file to your local machine

# Copy '/var/log/syslog' from the remote host to the current local directory
scp dev@example.com:/var/log/syslog .

No output means success — check with ls -l.

Example 3: Copy a directory recursively

# Copy a whole project folder recursively (note the -r flag)
scp -r ./project dev@example.com:/home/dev/project

Example 4: Use a custom SSH port and preserve timestamps

# If your SSH server runs on port 2222, and you want to preserve file timestamps
scp -P 2222 -p backup.tar.gz dev@example.com:/backups/

Pro tip: Test your SSH connection first with ssh dev@example.com — if that works, scp will work with the same options (like -i for a private key, -p for port).

Compare Options: When to Choose What

scp is not the only file transfer tool. Here's a quick comparison with two alternatives:

Tool Encryption Resume support Ease of use Best for
scp Yes (SSH) No (basic) Very easy, pre-installed Quick transfers, automation
rsync Yes (over SSH) Yes Requires rsync installed both ends Large/incremental backups
sftp Yes (SSH) No (but interactive) Interactive shell, also over SSH Manual file browsing, single files

When to use scp: Simple one-off transfers, no need for resume, and you want something that works out of the box.

When to use rsync: Large files or directories, need to resume interrupted transfers, or want to sync only changed parts. rsync can also use -e ssh to combine its power with SSH security.

When to use sftp: If you need to browse the remote filesystem interactively rather than specifying exact paths.

Variations: You can also use scp with IPv6 addresses (wrap them in brackets, e.g., scp file user@[2001:db8::1]:/tmp/), and you can configure ~/.ssh/config to define short host aliases, so scp file myserver:/tmp/ just works.

Troubleshooting & Edge Cases

  • Connection refused — The SSH daemon isn't running on the remote host, or a firewall is blocking port 22. Try ssh to the host; if that fails, fix the SSH service first.
  • Permission denied — Check that your user has write permission on the destination directory, and that your SSH key is correctly placed on the remote host (~/.ssh/authorized_keys). Use -v to see verbose diagnostics.
  • No such file or directory — Ensure the source path exists and you've quoted remote paths with spaces: scp "my file.log" user@host:"/home/user/My Files/".
  • Broken pipe or transfer stalls — This often happens with poor network or firewalls dropping idle connections. Try adding -o ServerAliveInterval=60 to keep the connection alive, or consider switching to rsync for resumable transfers.
  • File permission issues — If the remote file ends up with unexpected permissions, use -p to preserve them, or set umask correctly.
  • When the remote shell has a weird default — Some systems have restrictive scp configurations; use -O (legacy protocol) only if you must, but prefer updating the server.

What You Learned & What's Next

In this lesson, you've learned how to copy files securely with scp:

  • The core concept: scp = cp over SSH, with encryption and authentication.
  • The step-by-step network flow: SSH handshake, authentication, encrypted transfer.
  • Practical commands for copying local→remote, remote→local, and directories.
  • How to choose between scp, rsync, and sftp based on use case.
  • Common errors and fixes, including connection, permission, and network issues.

Up next in this track: you'll likely explore rsync for incremental transfers, or move on to automating transfers with cron or systemd timers. Either way, you now have a secure, reliable way to move files across hosts — a fundamental piece of your Linux · networking · telemetry toolkit.

Practice recap

Practice by creating a local file and copying it to a remote server you manage (or to localhost with a different username). Then try copying a directory with -r, and experiment with -v to see the underlying SSH connection details. After that, investigate how rsync differs by running it with -avz on the same data.

Common mistakes

  • Forgetting the -r flag when copying directories, leading to an error like scp: app2: not a regular file.
  • Using -p for port instead of -P — lowercase -p preserves permissions, while uppercase -P sets the port. Mixing them up leads to unexpected behavior.
  • Not quoting remote paths that contain spaces or special characters, causing scp to interpret them incorrectly.
  • Assuming scp can resume an interrupted transfer — it cannot; use rsync for that.

Variations

  1. Use rsync -avz -e ssh for incremental, resumable transfers over SSH.
  2. Use sftp for interactive file browsing and transfers over SSH.
  3. Configure ~/.ssh/config with host aliases to shorten scp commands.

Real-world use cases

  • Copying application logs from a production server to your local machine for debugging.
  • Uploading a configuration file or SSH key to a new server's home directory.
  • Transferring a database dump (e.g., .sql.gz) between servers on a private network.

Key takeaways

  • scp provides secure file transfer over SSH with encryption and authentication.
  • The syntax is scp [options] source destination, where remote paths use user@host:path.
  • Always use -r for directories and -P (uppercase) for a custom SSH port.
  • Test SSH connectivity first to isolate connection issues.
  • For large or resumable transfers, consider rsync or sftp instead of scp.
  • Quote paths with spaces and use verbose output (-v) for troubleshooting.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.