The SCP command in Linux securely copies files and directories between local and remote systems over SSH. It encrypts data in transit, supports keys and custom ports, and works with simple syntax like scp source target. Use it to transfer backups, configs, or web assets to servers quickly, with options for recursion, throttling, compression, and jump hosts.
If you manage servers or deploy websites, learning the SCP command in Linux saves time and keeps transfers secure. In this practical user guide, I’ll explain how SCP works, its syntax, reliable examples, security best practices, and pro tips from 12+ years running Linux, cloud, and hosting environments at scale (including YouStable’s infrastructure).
What Is SCP and How Does It Work?

SCP (Secure Copy) is a command-line utility that copies files between hosts using SSH for authentication and encryption. By default, it connects to TCP port 22 and supports passwords or SSH keys. Modern OpenSSH versions use the SFTP protocol under the hood for safer path handling, but the scp command and its familiar syntax remain available.
Key points:
- Encrypted in transit (same crypto and keys as SSH)
- Works local-to-remote, remote-to-local, and remote-to-remote
- Simple, predictable syntax with options for recursion, ports, bandwidth limits, compression, and jump hosts
- Ideal for quick, one-off transfers; for syncs/resume features, consider rsync
SCP Syntax (Explained in 60 Seconds)
The basic format is:
scp [options] source target
scp [options] [[user@]host1:]path1 [[user@]host2:]path2
Examples of source/target:
- Local file:
file.txtor./dir/file.txt - Remote file:
user@server:/path/to/file.txt - IPv6 host:
user@[2001:db8::1]:/path
Key rule: A trailing colon indicates a remote host. Without a colon, it’s a local path. For remote directories, add the path after the colon.
Essential SCP Examples (With Clear Use Cases)
1) Copy a file from local to remote
scp index.html user@server:/var/www/html/
Use this to upload web assets, configs, or scripts to a server. If the remote path is a directory, SCP places the file inside it.
2) Copy a file from remote to local
scp user@server:/etc/nginx/nginx.conf ./
Great for pulling logs or configuration backups from a server to your workstation.
3) Copy an entire directory (recursive)
scp -r ./site/ user@server:/var/www/html/
-r copies directories recursively. Add -p to preserve timestamps and permissions:
scp -rp ./site/ user@server:/var/www/html/
4) Specify a non-default SSH port
scp -P 2222 backup.tar.gz user@server:/backups/
Important: The port flag is uppercase -P (lowercase -p is “preserve”).
5) Use an SSH private key (PEM/ED25519/RSA)
scp -i ~/.ssh/id_ed25519 app.war ubuntu@server:/opt/apps/
You can also pass SSH config options generically:
scp -o IdentityFile=~/.ssh/key.pem -o IdentitiesOnly=yes file ubuntu@server:/home/ubuntu/
6) Handle spaces, hidden files, and wildcards
Quote paths with spaces, and quote remote wildcards so they expand on the remote host:
# Local file with spaces
scp "My Report.pdf" user@server:/home/user/docs/
# Remote wildcard: quote to prevent local shell expansion
scp 'user@server:/var/log/*.log' ./logs/
# Copy hidden files
scp -r ./app/.env user@server:/var/www/app/
7) Remote-to-remote copies (via your local machine)
Use -3 to copy between two remote servers, routing through your client (data passes through your machine):
scp -3 admin@hostA:/var/backups/db.sql admin@hostB:/var/restore/
8) Use a jump host (bastion)
For private servers behind a bastion, -J simplifies routing:
scp -J bastion@public-gw ubuntu@internal-app:/etc/hosts ./
Must-Know SCP Options and What They Do
-r: Recursive copy (directories)-p: Preserve timestamps, modes-P <port>: SSH port (uppercase P)-i <key>: Use identity file (private key)-o <ssh_option>: Pass SSH options (e.g.,-o StrictHostKeyChecking=yes)-C: Compression (helpful for text, configs, logs)-l <limit>: Limit bandwidth in Kbit/s (e.g.,-l 4000)-J <jump>: Jump host (bastion)-3: Remote-to-remote via local-4/-6: Force IPv4/IPv6-F <file>: Use alternate SSH config file-q/-v: Quiet / Verbose (add more v’s for debug)
SSH Keys and Config for Frictionless SCP
Password prompts slow you down and aren’t ideal for automation. Use SSH keys and an SSH config file for a smooth experience.
Generate a key and authorize it
# Create an ED25519 key (fast and secure)
ssh-keygen -t ed25519 -C "you@machine"
# Copy the public key to the server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
If ssh-copy-id isn’t available, paste the public key into ~/.ssh/authorized_keys on the server and set permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Simplify with ~/.ssh/config
Host web-prod
HostName 203.0.113.10
User ubuntu
IdentityFile ~/.ssh/id_ed25519
Port 22
Compression yes
# Then simply run:
scp ./build.zip web-prod:/var/www/html/
Security Best Practices for SCP
- Verify host keys on first connect; do not disable checks with
-o StrictHostKeyChecking=noexcept in controlled CI. - Prefer SSH keys over passwords; restrict keys with proper permissions and passphrases.
- Use least-privilege accounts; avoid using root unless necessary.
- Harden SSH: use a non-default port if appropriate, disable password auth, enforce strong ciphers and MACs.
- Audit transfers via logs (
/var/log/auth.logor system journal) in regulated environments.
Troubleshooting SCP (Quick Fixes)
Permission denied (publickey,password)
- Ensure you’re using the correct user and key (
-ior SSH config). - Check server-side permissions on
~/.ssh(700) andauthorized_keys(600). - Run
scp -vto see which key is attempted.
No such file or directory
- Quote remote paths/wildcards so your local shell doesn’t expand them.
- Confirm the directory exists on the target; create with
ssh user@server "mkdir -p /path"before copying. - Use absolute paths to avoid confusion with remote shell’s working directory.
Connection timed out or refused
- Check firewall/security groups for TCP 22 (or your custom port).
- Verify DNS or use the server’s IP; force IPv4 with
-4if needed. - Use
scp -vto diagnose port/host reachability and auth negotiation.
scp: command not found (remote)
On minimal images, ensure OpenSSH utilities are installed and the SFTP subsystem is enabled. Current OpenSSH scp uses SFTP by default, which must be available on the server.
Performance and Reliability Tips
- Use compression for text-heavy transfers:
scp -C logs.tar.gz user@server:/tmp/ - Choose fast ciphers if you have CPU headroom (varies by OpenSSH version), e.g.,
-c aes128-gcm@openssh.comor-c chacha20-poly1305@openssh.com. - Throttle to protect bandwidth:
scp -l 8000 big.img user@server:/data/(8000 Kbit/s ≈ 1 MB/s). - Parallelization: scp itself isn’t parallel or resumable. For large trees or flaky links, prefer
rsync -azPor SFTP with resume. - Avoid unnecessary encryption overhead on LAN by using faster ciphers; on WAN, compression can help.
SCP vs rsync vs SFTP: Which Should You Use?
- Use SCP when you need a quick, one-off, encrypted copy with simple syntax.
- Use rsync for incremental syncs, resume support, checksums, and robust directory mirroring.
- Use SFTP for interactive sessions, resumable uploads/downloads, and granular file operations.
- Use rclone for object storage (S3, GCS), cloud-native workflows, and cross-provider sync.
Note: Despite headlines about “SCP deprecation,” modern OpenSSH keeps the scp command but implements transfers over SFTP by default for safer behavior. You can keep using scp confidently on up-to-date systems.
Cloud Examples: AWS, GCP, Azure
- AWS EC2 (Ubuntu):
scp -i ~/keys/aws.pem app.tar.gz ubuntu@<public-ip>:/opt/ - AWS EC2 (Amazon Linux):
scp -i ~/keys/aws.pem site.zip ec2-user@<public-ip>:/var/www/html/ - GCP Compute Engine:
scp -i ~/.ssh/gcp ed@<external-ip>:/var/log/syslog ./(ensure firewall allows SSH) - Azure VM:
scp -P 22 -i ~/.ssh/azure key.pub azureuser@<public-ip>:~/.ssh/ - Behind a bastion:
scp -J user@bastion targetuser@10.0.0.10:/etc/nginx/nginx.conf ./
Automate SCP in Scripts and Cron
For nightly backups or CI deploys, pair keys with a locked-down user and explicit SSH options. Here’s a reliable pattern:
#!/usr/bin/env bash
set -euo pipefail
HOST="web-prod"
SRC_DIR="/var/backups"
DST_PATH="/backups/$(date +%F)"
LOG="/var/log/backup_scp.log"
mkdir -p "$SRC_DIR"
tar -czf "$SRC_DIR/site-$(date +%F).tar.gz" /var/www/html/
# Copy with compression, bandwidth limit, and strict host key checking
scp -C -l 8000 -o BatchMode=yes -o StrictHostKeyChecking=yes \
"$SRC_DIR/site-$(date +%F).tar.gz" "${HOST}:${DST_PATH}/" >> "$LOG" 2>&1
echo "Backup completed at $(date)" >> "$LOG"
Schedule with cron (crontab -e). For high-change datasets or large directories, switch to rsync to avoid re-uploading unchanged files.
Real-World Tips From Hosting Operations
- Quote remote globs:
scp 'user@host:/var/log/app/*.log' ./prevents local shell expansion errors. - Use host aliases in
~/.ssh/configto standardize ports, keys, and jump hosts across your team. - Deploy packs as archives (
tar.gz) rather than thousands of small files; SCP handles fewer, larger files more efficiently. - Throttle during business hours with
-lto protect customer traffic; remove the limit off-hours. - In CI/CD, force strict host key checks and pin host keys to prevent MITM risks.
FAQs: SCP Command in Linux
Is SCP deprecated? Should I still use it?
The scp command still exists and is maintained. Newer OpenSSH versions implement scp using SFTP by default for safer behavior. For quick, secure copies, SCP is fine; for resumable, incremental transfers, use rsync or SFTP.
How do I specify a port with SCP?
Use uppercase -P, for example: scp -P 2222 file user@server:/path/. Alternatively, set the Port in ~/.ssh/config for a host alias.
How do I copy an entire folder with SCP?
Add -r for recursion and -p to preserve metadata: scp -rp ./folder user@server:/path/. Consider rsync for large trees and repeated syncs.
How do I use a PEM/private key with SCP?
Use -i: scp -i ~/keys/key.pem file ubuntu@<ip>:/path/. You can also define IdentityFile in ~/.ssh/config for a cleaner command and set IdentitiesOnly yes.
Can SCP resume interrupted transfers?
No. SCP lacks native resume. Use rsync -P or SFTP’s reget/reput for resumable transfers, especially over unstable links or for large files.
Why does SCP keep asking for my password?
Likely missing or mismatched SSH keys, wrong user, or server-side perms on ~/.ssh/authorized_keys. Ensure correct -i file, set chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys, and verify your SSH config.
How do I verify that my SCP transfer succeeded?
SCP exits with 0 on success. For critical workflows, compare checksums: sha256sum file locally and remotely after transfer. For large directories, prefer rsync with checksums.
Wrapping Up
The SCP command in Linux offers a fast, secure, and straightforward way to move files across servers using SSH. Master the core options (-r, -p, -P, -i, -C, -J, -l), adopt SSH keys and configs, and lean on rsync/SFTP when you need resume and synchronization. With the right practices—and a reliable hosting partner like YouStable—you’ll transfer data safely and efficiently at any scale.