Linux 文件传输 SCP 命令详解 📁
🔒 基于 SSH 的安全文件传输协议,轻松在本地和远程系统间安全传输文件
📋 目录导航
🚀 SCP 简介
SCP(Secure Copy Protocol)是基于 SSH 的安全文件传输协议,用于在本地和远程系统之间安全地复制文件。它利用 SSH 进行数据加密和身份验证,确保传输过程的安全性。
主要特点:
- 🔒 加密传输:所有数据都通过 SSH 加密
- 🔐 身份验证:支持密码和密钥认证
- 📊 简单易用:命令行界面,学习成本低
- 🔄 跨平台:支持所有类 Unix 系统和 Windows(通过客户端)
适用场景:
- 快速安全地传输单个或少量文件
- 简单的远程文件备份
- 在可信网络环境中的文件交换
⚙️ 基本语法与选项
基本语法格式
常用选项表
选项 |
描述 |
示例 |
-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 命令指南能帮助您更好地管理和传输文件!🚀