scp Command: Usage and Options, Copying Folders and Specifying a Port

Test environmentRHEL familyAlmaLinux 9.8OpenSSH 9.9p1Receiving side Debian 12 · OpenSSH 9.2p1root accountChecked 2026-10-28

scp is a copy tool for exchanging files with a server you connect to over SSH. When you send a file with the scp command, you write the source first and the destination after it, just as with cp. When we sent files and folders from an AlmaLinux 9 server to a Debian 12 server and retrieved them, the transfer ran over the SFTP protocol and a 20MB file arrived in under a second.

All output below is exactly what scp from OpenSSH 9.9 printed under the root account on the sending side. Only the server addresses and account names were changed to example values.

1️⃣ scp usage and remote paths

Put [account@server address:] in front of a path on the remote server. A path without a colon is treated as a path on the server where you ran the command, so the side with the colon decides whether you are sending or receiving.

🧭 scp copy direction and remote paths
Explainer diagram
↔️ Copy direction
$ scp report.txt user@203.0.113.10:~/scp-test/user@203.0.113.10:~/scp-test/report.txt ./downloads/-3 user@203.0.113.10:~/scp-test/report.txt user@198.51.100.20:~/scp-test/
source💻 Server running the commandreport.txt
➜
destination🖥️ Remote server203.0.113.10:~/scp-test/
source🖥️ Remote server203.0.113.10:~/scp-test/report.txt
➜
destination💻 Server running the command./downloads/
source🖥️ Remote server A203.0.113.10:~/scp-test/report.txt
➜
Relay💻 Server running the command-3
➜
destination🖥️ Remote server B198.51.100.20:~/scp-test/
🧩 Remote path format
user the account to connect with, 203.0.113.10 the server address or domain, :~/scp-test/ and after the colon, a path on that server (the tilde means the home folder)
With the local file first and the remote path after it, you are sending. If the path after the colon ends in a slash, the file is saved inside that folder under the same name.
With the remote path first, you are receiving. The received file ends up at the local path you wrote after it.
When both source and destination are remote servers, from OpenSSH 8.7 the data passes through the server running the command. This is the same method as adding -3.

Send report.txt from the current folder to the scp-test folder under the remote server's home.

scp report.txt user@203.0.113.10:~/scp-test/
report.txt                                    100%   14     5.1KB/s   00:00

When the transfer finishes, the file name, progress, size, speed and elapsed time appear on one line. This progress display only appears when you run scp in a terminal, so if you redirect the output to a file, nothing ends up in that file.

To fetch a file, write the remote path first and the local path to save to after it.

scp user@203.0.113.10:~/scp-test/report.txt ./downloads/
report.txt                                    100%   14     2.7KB/s   00:00

If the destination path ends in a file name rather than a folder, the file is saved under that name. After sending with the command below, report.txt sat in the receiving folder as report-1028.txt.

scp report.txt user@203.0.113.10:~/scp-test/report-1028.txt
report.txt                                    100%   14     4.6KB/s   00:00

🔲 scp command simulator

In the simulator below you can type send, receive and folder copy commands yourself and check the output for each option.

scp command simulatorOpenSSH 9.9
[root@server work]#
This runs only in your browser. Check the remote files in the list on the left, and use ↑↓ to recall earlier commands.

2️⃣ scp command options

Options go right after scp, before the source. -P for the port is uppercase and lowercase -p preserves times and permissions, so mixing up the case runs a different action.

-l sets an upper limit on transfer speed in Kbit/s. Without options, a 20MB file finished transferring in under a second.

scp backup.tar.gz user@203.0.113.10:~/scp-test/
backup.tar.gz                                 100%   20MB  53.6MB/s   00:00

-l 8000 works out to about 1,000KB per second. When we sent the same file with -l 8000, the progress display showed 996.5KB/s and the transfer took 20 seconds.

scp -l 8000 backup.tar.gz user@203.0.113.10:~/scp-test/backup-l.tar.gz
backup.tar.gz                                 100%   20MB 996.5KB/s   00:20

-C compresses data on the SSH connection in the same way as gzip. We sent a 19MB log file full of repeated sentences three times each, and between these two servers the runs with -C were slightly slower.

CommandfileRun timeProgress display speed
scp backup.tar.gz20MB0.68 s53.6MB/s
scp -l 8000 backup.tar.gz20MB20.82 s996.5KB/s
scp access.log (3 runs)19MB0.79~0.89 s—
scp -C access.log (3 runs)19MB0.84~0.97 s—

Run time is the time from starting the command through connecting to finishing the transfer. The ssh manual also says compression helps on slow lines and slows transfers down on fast networks.

-v prints the steps from connecting to transferring as debug1 lines, so use it to find the cause when a connection fails or stalls at authentication. The output is long, so we picked out only the authentication and transfer lines with grep.

scp -v report.txt user@203.0.113.10:~/scp-test/ 2>&1 | grep -E 'Authenticated|Sending|Transferred'
Authenticated to 203.0.113.10 ([203.0.113.10]:22) using "publickey".
debug1: Sending subsystem: sftp
Transferred: sent 2536, received 3248 bytes, in 0.1 seconds

The [Sending subsystem: sftp] line means scp sent the file over the SFTP protocol. From OpenSSH 9.0, scp uses SFTP by default. Adding -O transfers over the legacy SCP protocol, and [Sending command: scp -v -t] appears in the same place.

scp -O -v report.txt user@203.0.113.10:~/scp-test/ 2>&1 | grep -E 'Authenticated|Sending|Transferred'
Authenticated to 203.0.113.10 ([203.0.113.10]:22) using "publickey".
debug1: Sending command: scp -v -t ~/scp-test/
Sending file modes: C0600 14 report.txt
Transferred: sent 2328, received 3036 bytes, in 0.1 seconds

📌 Main options: results from this article

OptionTaskResult in this article
-PSpecifies the SSH connection portPort 22 finished sending report.txt, while closed port 2222 ended with [Connection timed out]
-iSpecifies the private key file for public key authenticationFinished sending report.txt with ~/.ssh/id_ed25519 specified
-rCopies a folder's files and subfolderscss and images folders remain on the receiving side in the original structure; without it, the [not a regular file] error stops the transfer
-pPreserves the source's modification time, access time and permissionsModification time preserved; on this article's receiving side, permission 600 was kept only for the file sent with -O -p
-CCompresses data on the SSH connectionFor the 19MB log between this article's two servers, the run with it was slightly slower
-lSets an upper limit on transfer speed in Kbit/sWith -l 8000, 20MB ran at 996.5KB/s in 20.82 seconds
-vPrints the steps from connecting to transferring as debug1 linesSFTP transfer confirmed by the [Sending subsystem: sftp] line
-3Transfers data between two remote servers through the server running the command (the default from OpenSSH 8.7)Finished sending report.txt with two folders on the same server as source and destination
-OTransfers over the legacy SCP protocol[Sending command: scp -v -t] appears in the -v output; paths with spaces need an extra backslash
-oPasses an option in ssh_config format to sshSet the wait to 10 seconds with ConnectTimeout=10 and confirmed [Connection timed out]

📎 Other options: per the official manual

OptionTask
-qTurns off the progress display and ssh warnings and diagnostic messages
-JConnects to a jump host first, then sets up TCP forwarding from there to the final destination (shorthand for the ProxyJump setting; separate multiple hops with commas)
-FUses a different file as ssh's per-user configuration file (passed directly to ssh)
-4Forces use of IPv4 addresses only
-6Forces use of IPv6 addresses only

3️⃣ Copying folders with scp and preserving times

If you give a folder without options, scp prints an error saying it is not a regular file and does not proceed with the transfer.

scp site-files user@203.0.113.10:~/scp-test/
scp: local "site-files" is not a regular file
scp: failed to upload file site-files to ~/scp-test/

With -r, scp copies the files and subfolders inside the folder.

scp -r site-files user@203.0.113.10:~/scp-test/
logo.png                                      100%   48KB   4.7MB/s   00:00
style.css                                     100%   15     5.0KB/s   00:00
index.html                                    100%   15     5.2KB/s   00:00

The output shows only file names. The find output on the receiving side showed the css and images folders under site-files in the original structure.

ssh user@203.0.113.10 'cd ~/scp-test && find site-files'
site-files
site-files/images
site-files/images/logo.png
site-files/index.html
site-files/css
site-files/css/style.css

-r follows symbolic links inside the folder and copies the files they point to, so for folders where links must stay links, use rsync -a.

-p preserves the source's modification time, access time and permissions. We set the source report.txt to a modification time of October 1, 2026 00:00 (UTC) and permissions of 600 before sending it. The receiving server's time zone is UTC, so ls on the sending side also printed with TZ=UTC.

TZ=UTC ls -l report.txt
-rw------- 1 root root 14 Oct  1 00:00 report.txt
scp -p report.txt user@203.0.113.10:~/scp-test/report-p.txt
report.txt                                    100%   14     4.7KB/s   00:00
scp -O -p report.txt user@203.0.113.10:~/scp-test/report-Op.txt
report.txt                                    100%   14     4.2KB/s   00:00
ssh user@203.0.113.10 'ls -l ~/scp-test/report.txt ~/scp-test/report-p.txt ~/scp-test/report-Op.txt'
-rw------- 1 user user 14 Oct  1 00:00 /home/user/scp-test/report-Op.txt
-rw-rw-r-- 1 user user 14 Oct  1 00:00 /home/user/scp-test/report-p.txt
-rw-rw-r-- 1 user user 14 Oct 28 06:17 /home/user/scp-test/report.txt

report-p.txt sent with -p and report-Op.txt sent with -O -p kept the source time, while report.txt sent without options was saved with the time it was sent. On the receiving server, files sent over SFTP were saved with permissions of 664 even with -p, and only the file sent over the legacy SCP protocol (-O) kept 600.

So for files whose permissions must match the source, check the permissions with ls -l on the receiving side after sending.

4️⃣ Specifying a port and key file with scp

For servers you cannot reach with the default port 22 and default key, specify the port and key yourself before sending. -P specifies the SSH connection port and -i specifies the private key file for public key authentication.

Below is an example that specifies port 22 and a key file directly. On a server with a changed port, write that number instead of 22.

scp -P 22 -i ~/.ssh/id_ed25519 report.txt user@203.0.113.10:~/scp-test/
report.txt                                    100%   14     5.3KB/s   00:00

Without -i, scp works through the keys with default names under ~/.ssh (id_rsa, id_ecdsa, id_ed25519 and so on) in turn, just as ssh does.

If you send to the same server often, write an alias in ~/.ssh/config and type only the alias in scp.

Host myserver
    HostName 203.0.113.10
    User user
    Port 22
    IdentityFile ~/.ssh/id_ed25519

The name on the Host line becomes the alias, and the four lines under it stand in for the server address, account, port and key file. The command with only the alias finished with the same one-line result as when we wrote out the address and key.

scp report.txt myserver:~/scp-test/
report.txt                                    100%   14     4.2KB/s   00:00

-P, -i and aliases all use your ssh connection settings as they are, so creating a key and registering it on the server also works the same way as connecting with the SSH command.

5️⃣ Copying between servers with scp

Even when both source and destination are remote servers, one line of scp can do the copy. From OpenSSH 8.7, data is transferred through the server running the command, and this method is -3. The official release notes give not having to keep the destination server's credentials on the source server as the reason for making it the default.

The measurement below used two folders on the same server as source and destination. If the destination is a different server, change only the account and address at the end.

scp -3 user@203.0.113.10:~/scp-test/report.txt user@203.0.113.10:~/scp-test/copy3/
report.txt                                    100%   14     2.5KB/s   00:00

It is like head office receiving documents from one branch and forwarding them to another.

The old method, in which the source server sends directly to the destination server, is specified with -R. It requires that the source server can connect to the destination server without a password. From OpenSSH 10.6, using -R prints a deprecation warning, and later versions are planned to ignore this option and copy with the -3 method.

6️⃣ scp vs rsync

scp is enough for sending a few files once, but for repeatedly syncing the same folder or resuming an interrupted transfer, use the rsync command. scp sends every file you specify again on each run, while rsync compares source and destination and transfers only the changed files.

Itemscprsync
Transfer scopeAll specified files on every runOnly files changed from the source
Keep partially received files (--partial)❌✅
Delete files not in the source (--delete)❌✅
Symbolic linksFollows them and copies the filesKeeps links as links with -a
Needed on the receiving sideSSH access and an SFTP serverrsync installed on both sides

7️⃣ scp error messages and fixes

When scp fails, the cause appears right on the first line of output. In the three cases where we deliberately triggered errors with a missing file, write permissions and a wrong port, the cause was on the first line every time and the exit code was non-zero every time.

🔲 No such file or directory

If you try to fetch a file that does not exist on the remote side, [No such file or directory] is printed with the path.

scp user@203.0.113.10:~/scp-test/nofile.txt ./downloads/
scp: ~/scp-test/nofile.txt: No such file or directory

The same error appears when the destination folder does not exist on send. scp does not create missing folders, so run mkdir -p over ssh first to create the folder.

scp report.txt user@203.0.113.10:~/scp-test/nodir/sub/
scp: dest open "scp-test/nodir/sub/": No such file or directory
scp: failed to upload file report.txt to ~/scp-test/nodir/sub/

🔲 Permission denied

If the receiving folder has no write permission, [dest open] is followed by [Permission denied]. Below is the result of sending to a readonly folder with permissions of 555.

scp report.txt user@203.0.113.10:~/scp-test/readonly/
scp: dest open "scp-test/readonly/report.txt": Permission denied
scp: failed to upload file report.txt to ~/scp-test/readonly/

If [Permission denied] is preceded by [account@server address:] and the parentheses contain an authentication method such as publickey, the connection was refused at the authentication stage. This wording is the format the ssh program uses when authentication fails, so start by checking the key file specified with -i and the public key registered on the server.

🔲 Connection timed out

If the port number is wrong or a firewall blocks that port so no response comes back, scp waits for the connection and ends with [Connection timed out]. Below is the result of sending to closed port 2222 with the wait set to 10 seconds.

scp -P 2222 -o ConnectTimeout=10 report.txt user@203.0.113.10:~/scp-test/
ssh: connect to host 203.0.113.10 port 2222: Connection timed out
scp: Connection closed

When you get this error, first check that the number given to -P matches the server's SSH port.

🔲 Spaces and the tilde (~) in paths

Today's scp, which transfers over SFTP, only needs a remote path containing spaces to be wrapped once in single quotes.

scp report.txt 'user@203.0.113.10:~/scp-test/my files/'
report.txt                                    100%   14     4.7KB/s   00:00

When we added -O to the same command to send over the legacy SCP protocol, it failed with [ambiguous target]. This is because the remote shell interprets the path once more in the legacy SCP protocol.

scp -O report.txt 'user@203.0.113.10:~/scp-test/my files/'
scp: ambiguous target

In that case, put a backslash before the space so the remote shell also reads it as one word.

scp -O report.txt 'user@203.0.113.10:~/scp-test/my\ files/'
report.txt                                    100%   14     4.5KB/s   00:00

A path after the colon that starts without a slash or tilde is handled relative to the remote account's home folder.

scp report.txt user@203.0.113.10:scp-test/report-rel.txt
report.txt                                    100%   14     5.6KB/s   00:00

The official manual says to use -O when an old SFTP server cannot expand a path starting with a tilde to the home folder. In that case, writing a path relative to home without the tilde, as above, also saves to the same place.

🔢 FAQ & Recommended Content

If a file with the same name exists, scp overwrites it with the new file without asking. When we sent the same report.txt to the same folder several times, it transferred each time with no confirmation prompt. So for files you need to keep, send with a different name at the end of the destination path.

If you put * in the remote path and wrap it in single quotes, scp fetches every file on the remote server whose name matches. Fetching report-*.txt from the remote server transferred the six matching files in turn. The quotes stop the shell on the server running the command from expanding * first.

With -B, scp runs in batch mode, which does not ask for a password or passphrase. According to the official manual, you cannot enter a password in this mode, so set up key authentication first for automated jobs such as cron.

🧭 Network commands: recommended reading 13 posts · 2 references
🗂️ Network commands
📄 ip command 📄 netstat · ifconfig commands 📄 nmtui command
📄 SSH command 📄 rsync command 📄 wget command 📄 rz · sz commands 📄 scp command
📄 host command 📄 nslookup command
📄 iptables command 📄 firewall-cmd command 📄 certbot command

ℹ️ Affiliate Disclosure
This site's content contains affiliate links. When a visitor buys a product or service through one of them, the site receives a commission from the seller. The amount the buyer pays(it goes down during event discounts ↓)does not go up. Posted prices, discounts, and stock reflect the time of writing and may differ, so confirm with the seller before buying. Products are chosen and reviewed by our own standards, and commissions do not affect the order or content of reviews.

Leave a Reply

Your email address will not be published. Required fields are marked *

Prove your humanity: 5   +   3   =