Linux 文件传输 SCP 命令详解 📁

🔒 基于 SSH 的安全文件传输协议,轻松在本地和远程系统间安全传输文件


📋 目录导航


🚀 SCP 简介

SCP(Secure Copy Protocol)是基于 SSH 的安全文件传输协议,用于在本地和远程系统之间安全地复制文件。它利用 SSH 进行数据加密和身份验证,确保传输过程的安全性。

主要特点

  • 🔒 加密传输:所有数据都通过 SSH 加密
  • 🔐 身份验证:支持密码和密钥认证
  • 📊 简单易用:命令行界面,学习成本低
  • 🔄 跨平台:支持所有类 Unix 系统和 Windows(通过客户端)

适用场景

  • 快速安全地传输单个或少量文件
  • 简单的远程文件备份
  • 在可信网络环境中的文件交换

⚙️ 基本语法与选项

基本语法格式

1
scp [选项] 源文件 目标路径

常用选项表

选项 描述 示例
-P 指定远程主机的 SSH 端口(默认为 22) scp -P 2222 file.txt user@host:/path/
-r 递归复制整个目录 scp -r directory/ user@host:/path/
-C 启用压缩传输 scp -C largefile.iso user@host:/path/
-i 指定身份文件(私钥) scp -i ~/.ssh/key.pem file.txt user@host:/path/
-v 显示详细传输信息 scp -v file.txt user@host:/path/
-p 保留文件原属性(时间戳、权限等) scp -p file.txt user@host:/path/
-q 安静模式,不显示传输进度 scp -q file.txt user@host:/path/
-l 限制带宽使用(单位:Kbit/s) scp -l 1000 file.txt user@host:/path/
-c 指定加密算法 scp -c aes128-ctr file.txt user@host:/path/
-o 传递 SSH 配置选项 scp -o "ServerAliveInterval=60" file.txt user@host:/path/

📤 本地文件 → 远程服务器

基本用法

1
2
3
4
5
6
7
8
9
10
11
# 传输单个文件
scp local_file.txt username@remote_host:/remote/directory/

# 指定端口(如果SSH服务不在默认端口)
scp -P 2222 local_file.txt username@remote_host:/remote/directory/

# 保持文件属性(时间戳、权限等)
scp -p local_file.txt username@remote_host:/remote/directory/

# 使用密钥认证
scp -i ~/.ssh/private_key.pem local_file.txt username@remote_host:/remote/directory/

批量传输示例

1
2
3
4
5
6
7
8
# 传输多个文件
scp file1.txt file2.txt file3.txt username@remote_host:/remote/directory/

# 使用通配符
scp *.txt username@remote_host:/remote/directory/

# 传输目录及其内容
scp -r my_directory/ username@remote_host:/remote/path/

高级用法

1
2
3
4
5
6
7
8
# 限制带宽(1MB/s = 8000 Kbit/s)
scp -l 8000 large_file.iso username@remote_host:/remote/path/

# 启用压缩(对文本文件效果明显)
scp -C source_code.tar.gz username@remote_host:/remote/path/

# 使用特定加密算法
scp -c aes128-gcm@openssh.com sensitive_file.txt username@remote_host:/remote/path/

📥 远程服务器 → 本地

基本下载操作

1
2
3
4
5
6
7
8
# 下载单个文件
scp username@remote_host:/remote/path/file.txt /local/directory/

# 下载到当前目录
scp username@remote_host:/remote/path/file.txt .

# 下载整个目录
scp -r username@remote_host:/remote/directory/ /local/path/

高级下载技巧

1
2
3
4
5
6
7
8
9
10
11
# 使用密钥认证下载
scp -i ~/.ssh/private_key.pem username@remote_host:/remote/file.txt ./

# 保持文件属性
scp -p username@remote_host:/remote/file.txt /local/path/

# 限制带宽下载
scp -l 5000 username@remote_host:/remote/large_file.iso ./

# 从非标准端口下载
scp -P 2222 username@remote_host:/remote/file.txt ./

批量下载

1
2
3
4
5
6
7
8
# 下载多个特定文件
scp username@remote_host:'/path/file1.txt /path/file2.txt' /local/dir/

# 使用通配符下载
scp username@remote_host:'/path/*.log' /local/logs/

# 下载并重命名
scp username@remote_host:/remote/path/file.txt /local/path/new_name.txt

🔀 服务器之间传输

通过本地中转

1
2
3
4
5
6
# 从服务器A下载再到服务器B上传
scp user1@host1:/path/to/file.txt .
scp file.txt user2@host2:/path/to/destination/

# 使用管道一步完成
scp -3 user1@host1:/path/file.txt user2@host2:/path/

直接服务器间传输

1
2
3
4
5
6
7
# 需要配置SSH密钥信任
# 首先在host1上生成密钥并复制到host2
ssh-keygen -t rsa
ssh-copy-id user2@host2

# 然后在host1上直接传输到host2
scp /local/path/file.txt user2@host2:/remote/path/

高级跨服务器操作

1
2
3
4
5
# 使用tar压缩传输目录
ssh user1@host1 "tar czf - /path/to/source/" | ssh user2@host2 "tar xzf - -C /path/to/dest/"

# 排除某些文件传输
ssh user1@host1 "tar czf - --exclude='*.tmp' /path/to/source/" | ssh user2@host2 "tar xzf - -C /path/to/dest/"

🎯 高级用法技巧

1. 批量文件传输

1
2
3
4
5
6
7
8
9
10
# 使用循环传输多个文件
for file in *.txt; do
scp "$file" username@remote_host:/remote/directory/
done

# 结合find命令传输特定文件
find . -name "*.log" -exec scp {} username@remote_host:/remote/logs/ \;

# 使用rsync模式(需要预先安装rsync)
rsync -avz -e ssh local/ username@remote_host:/remote/path/

2. 进度显示和监控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 使用pv工具显示进度(需要安装pv)
tar cf - directory/ | pv | ssh username@remote_host "tar xf - -C /path/"

# 使用rsync代替scp显示进度
rsync -avz --progress local/ username@remote_host:/remote/path/

# 自定义进度显示函数
scp_with_progress() {
local src="$1"
local dst="$2"
local size=$(du -sb "$src" | cut -f1)
scp -q "$src" "$dst" &
local pid=$!

while kill -0 "$pid" 2>/dev/null; do
local current=$(ssh username@remote_host "du -sb /remote/path/$(basename "$src") 2>/dev/null" | cut -f1)
local percent=$((current * 100 / size))
printf "Progress: %d%%\r" "$percent"
sleep 1
done
echo "Transfer complete!"
}

3. 断点续传方案

1
2
3
4
5
6
7
8
9
10
11
# 使用rsync实现断点续传
rsync -avz --partial --progress largefile.iso username@remote_host:/path/

# 分割大文件传输
split -b 100M largefile.iso largefile.part.
scp largefile.part.* username@remote_host:/path/
ssh username@remote_host "cat /path/largefile.part.* > /path/largefile.iso && rm /path/largefile.part.*"

# 校验文件完整性
ssh username@remote_host "md5sum /path/largefile.iso"
md5sum largefile.iso

⚡ 性能优化

1. 加密算法选择

1
2
3
4
5
6
7
8
# 测试不同加密算法的速度
for cipher in aes128-ctr aes192-ctr aes256-ctr aes128-gcm@openssh.com aes256-gcm@openssh.com; do
echo "Testing $cipher"
time scp -c "$cipher" largefile.iso username@remote_host:/dev/null
done

# 使用最快速的加密算法
scp -c aes128-gcm@openssh.com large_file.iso username@remote_host:/path/

2. 压缩传输优化

1
2
3
4
5
6
7
8
9
10
11
12
# 启用压缩(对文本、代码等可压缩文件有效)
scp -C source_code.tar.gz username@remote_host:/path/

# 自定义压缩级别(结合tar使用)
tar -I 'gzip -9' -cf - directory/ | ssh username@remote_host "tar xf - -C /path/"

# 根据文件类型决定是否压缩
if file "$1" | grep -q "text"; then
scp -C "$1" username@remote_host:/path/
else
scp "$1" username@remote_host:/path/
fi

3. 并行传输加速

1
2
3
4
5
6
7
8
9
10
11
# 使用多个scp会话并行传输
for file in *.iso; do
scp "$file" username@remote_host:/path/ &
done
wait

# 使用xargs控制并行度
find . -name "*.log" -print0 | xargs -0 -P 4 -I {} scp {} username@remote_host:/path/

# 使用parallel工具(需要安装)
parallel -j 4 scp {} username@remote_host:/path/ ::: *.iso

4. 连接复用

1
2
3
4
5
6
7
8
9
# 配置SSH连接复用(添加到~/.ssh/config)
Host *
ControlMaster auto
ControlPath ~/.ssh/control:%h:%p:%r
ControlPersist 1h

# 然后SCP会复用SSH连接,加快后续传输
scp file1.txt username@remote_host:/path/ # 建立连接
scp file2.txt username@remote_host:/path/ # 复用连接

🔄 替代方案比较

SCP 与其它工具对比

工具 优点 缺点 适用场景
SCP 简单易用,所有SSH服务器都支持 无断点续传,性能较差 小文件快速传输
Rsync 支持断点续传,增量传输,性能优化 配置稍复杂,需两端安装 大文件、定期同步
SFTP 交互式操作,功能丰富,支持文件管理 速度较慢,不适合脚本化 交互式文件管理
FTP/FTPS 广泛支持,多客户端,可恢复传输 安全性较差,配置复杂 传统文件共享
HTTP/HTTPS 穿透防火墙,无需特殊客户端 需要Web服务器,安全性依赖配置 公开文件分发

何时选择 SCP

  • 传输小文件(<100MB)
  • 简单的一次性文件传输
  • 环境限制只能使用SSH的情况
  • 需要最小化依赖项

何时选择其它工具

  • 大文件传输 → 使用 Rsync
  • 需要断点续传 → 使用 Rsync 或 SFTP
  • 交互式文件管理 → 使用 SFTP
  • 多客户端共享 → 使用 FTP/FTPS 或 HTTP/HTTPS

🐛 故障排除

1. 常见错误解决

1
2
3
4
5
6
7
8
9
10
11
12
# 权限被拒绝错误
chmod 600 ~/.ssh/private_key.pem # 确保密钥权限正确
chmod 755 ~/ # 确保家目录权限正确

# 连接超时问题
scp -o ConnectTimeout=30 -o ServerAliveInterval=60 file.txt username@remote_host:/path/

# 主机密钥验证失败
ssh-keyscan -H remote_host >> ~/.ssh/known_hosts

# 内存不足错误
scp -l 512 large_file.iso username@remote_host:/path/ # 限制带宽减少内存使用

2. 调试模式

1
2
3
4
5
6
7
8
# 显示详细调试信息
scp -v file.txt username@remote_host:/path/

# 使用SSH调试模式
scp -o LogLevel=DEBUG3 file.txt username@remote_host:/path/

# 检查详细错误信息
scp -v file.txt username@remote_host:/path/ 2>&1 | grep -i error

3. 网络诊断

1
2
3
4
5
6
7
8
9
10
11
12
# 测试网络连通性
ping remote_host

# 测试SSH连接
ssh -v username@remote_host

# 测试端口连通性
telnet remote_host 22
nc -zv remote_host 22

# 检查防火墙设置
sudo iptables -L # 查看防火墙规则

4. 性能问题诊断

1
2
3
4
5
6
7
8
# 检查网络速度
iperf3 -c remote_host # 需要安装iperf3

# 检查磁盘IO性能
ssh username@remote_host "dd if=/dev/zero of=testfile bs=1G count=1 oflag=direct"

# 检查系统负载
ssh username@remote_host "uptime; iostat -x 1 3"

🔒 安全建议

1. 认证安全

1
2
3
4
5
6
7
8
9
10
# 使用密钥认证代替密码认证
ssh-keygen -t ed25519 -C "your_email@example.com"
ssh-copy-id username@remote_host

# 禁用密码认证(在远程服务器上)
sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart sshd

# 使用强密码保护密钥
ssh-keygen -p -f ~/.ssh/id_rsa

2. 传输安全

1
2
3
4
5
6
7
8
# 使用更安全的加密算法
scp -c aes256-gcm@openssh.com sensitive_file.txt username@remote_host:/path/

# 验证主机密钥指纹
ssh-keyscan -H remote_host | ssh-keygen -lf -

# 使用VPN增强安全性(先建立VPN连接)
scp -o "ProxyCommand=nc -X connect -x vpn-proxy:port %h %p" file.txt username@remote_host:/path/

3. 访问控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 限制用户可以访问的目录(在远程服务器上)
# 创建受限用户
sudo useradd -m -s /bin/rbash restricted_user
sudo chmod 755 /home/restricted_user
sudo mkdir /home/restricted_user/files
sudo chown restricted_user:restricted_user /home/restricted_user/files
sudo chmod 700 /home/restricted_user/files

# 设置SCP专用用户
sudo useradd -m -s /usr/lib/openssh/sftp-server scp_user
sudo chown root:root /home/scp_user
sudo chmod 755 /home/scp_user
sudo mkdir /home/scp_user/uploads
sudo chown scp_user:scp_user /home/scp_user/uploads
sudo chmod 700 /home/scp_user/uploads

4. 监控和审计

1
2
3
4
5
6
7
8
# 监控SCP连接
sudo tail -f /var/log/auth.log | grep scp

# 设置SCP操作日志
sudo auditctl -a always,exit -F arch=b64 -S connect -S accept -S bind -S listen -F exe=/usr/bin/scp

# 定期检查授权密钥
ssh-keygen -l -f ~/.ssh/authorized_keys

📊 性能测试

1. 测试传输速度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建测试文件
dd if=/dev/zero of=testfile bs=1M count=100
echo "测试文件创建完成"

# 测量传输时间
echo "开始SCP传输测试..."
time scp testfile username@remote_host:/tmp/
echo "传输完成"

# 计算传输速度(MB/s)
filesize=100 # 文件大小MB
duration=$(time scp testfile username@remote_host:/tmp/ 2>&1 | grep real | awk '{print $2}' | awk -F'm' '{print $1 * 60 + $2}')
speed=$(echo "scale=2; $filesize / $duration" | bc)
echo "传输速度: $speed MB/s"

# 清理测试文件
ssh username@remote_host "rm /tmp/testfile"
rm testfile

2. 比较不同工具性能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建大测试文件
dd if=/dev/zero of=large_testfile bs=1M count=1024

# SCP速度测试
echo "测试SCP性能..."
time scp large_testfile username@remote_host:/tmp/

# Rsync速度测试
echo "测试Rsync性能..."
time rsync -avz large_testfile username@remote_host:/tmp/

# 记录结果
echo "SCP时间: $scp_time"
echo "Rsync时间: $rsync_time"

# 清理
rm large_testfile
ssh username@remote_host "rm /tmp/large_testfile"

3. 不同加密算法性能测试

1
2
3
4
5
6
# 测试不同加密算法的性能
for cipher in aes128-ctr aes192-ctr aes256-ctr aes128-gcm@openssh.com aes256-gcm@openssh.com; do
echo "测试加密算法: $cipher"
time scp -c "$cipher" testfile username@remote_host:/dev/null
echo ""
done

4. 网络条件模拟测试

1
2
3
4
5
6
7
8
9
10
11
12
# 使用tc模拟网络条件(需要root权限)
# 模拟高延迟
sudo tc qdisc add dev eth0 root netem delay 100ms

# 模拟带宽限制
sudo tc qdisc add dev eth0 root tbf rate 1mbit burst 32kbit latency 400ms

# 进行传输测试
time scp testfile username@remote_host:/tmp/

# 清除网络限制
sudo tc qdisc del dev eth0 root

🎯 提示: SCP 是一个简单而强大的文件传输工具,通过合理使用各种选项和技巧,可以大大提高文件传输的效率和可靠性。对于生产环境中的大量文件传输,建议考虑使用 rsync 或其他专门的文件同步工具。

希望这份完整的 SCP 命令指南能帮助您更好地管理和传输文件!🚀