scp / sftp / sshfs —— 跨机拷文件
scp / sftp / sshfs —— 跨机拷文件
分类:03 文件与传输 适用:全平台(OpenSSH 客户端) 一句话:临时传文件用
scp,交互浏览用sftp,把远端目录当本地盘用sshfs。
1. 三者怎么选
| 工具 | 特点 | 适用 |
|---|---|---|
scp |
单次命令、简单、全量传 | 临时拷一两个文件 |
sftp |
交互式、可 ls/cd/get/put、支持批处理 |
浏览远端目录、挑文件 |
sshfs |
挂载远端目录到本地 | 长期编辑远端文件、IDE 直接打开 |
rsync |
增量、断点续传、可删除同步 | 大目录/反复同步,优先用它 |
OpenSSH 9.0 起
scp默认走 SFTP 协议(更安全,但通配符行为有变化)。要恢复旧行为用scp -O。
2. scp 基础
scp file.txt user@host:/tmp/ # 上传
scp user@host:/tmp/file.txt ./ # 下载
scp -r dir/ user@host:/data/ # 递归上传
scp -r user@host:/data/dir ./ # 递归下载
scp file1 file2 user@host:/tmp/ # 多文件
scp user@host:'/data/*.log' ./ # 通配(引号防止本地展开)
scp -P 2222 file user@host:/tmp/ # 非标端口(大写 P)
scp -i ~/.ssh/id_ed25519 file user@host:/tmp/ # 指定私钥
scp -C file user@host:/tmp/ # 压缩传输(文本有效)
scp -l 8000 file user@host:/tmp/ # 限速 8000 Kbit/s
scp -p file user@host:/tmp/ # 保留时间戳与权限
scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ...
两个主机之间直接传
scp user1@host1:/data/file user2@host2:/data/
# 数据经过本地中转,慢;大文件用 rsync 或先跳到目标机执行
-3 选项(经本地转发)
某些实现支持 -3 让两台远端直接通过本地中转,行为与默认类似,但会正确转发凭据。
3. sftp 交互使用
sftp user@host
sftp -P 2222 user@host
sftp -i ~/.ssh/id_ed25519 user@host
常用命令:
| 命令 | 作用 |
|---|---|
ls / lls |
远端 / 本地列表 |
cd / lcd |
远端 / 本地切目录 |
pwd / lpwd |
远端 / 本地当前目录 |
get file |
下载 |
get -r dir |
递归下载 |
put file |
上传 |
put -r dir |
递归上传 |
mget *.log |
批量下载(支持通配) |
mput *.txt |
批量上传 |
rm / mkdir / rmdir |
远端操作 |
chmod 644 file |
改权限 |
df -h |
远端磁盘(! 执行本地命令,df 直接执行远端命令需 sftp 支持) |
!command |
执行本地 shell 命令 |
reget / reput |
断点续传 |
bye / exit |
退出 |
批处理(脚本化,推荐):
cat > /tmp/sftp_batch <<'EOF'
cd /data/backup
lcd /local/backup
mget *.tar.gz
bye
EOF
sftp -b /tmp/sftp_batch user@host
-b 模式下不会交互提示,失败会中断;-B 可指定缓冲区大小提升吞吐:
sftp -B 262144 -b /tmp/sftp_batch user@host
4. sshfs 挂载远端目录
# 安装
apt install -y sshfs
dnf install -y fuse-sshfs
# 挂载
mkdir -p /mnt/remote
sshfs user@host:/data /mnt/remote
# 指定端口与密钥
sshfs -p 2222 -o IdentityFile=~/.ssh/id_ed25519 user@host:/data /mnt/remote
# 常用挂载选项
sshfs -o reconnect,ServerAliveInterval=15,ServerAliveCountMax=3 \
-o uid=$(id -u),gid=$(id -g) user@host:/data /mnt/remote
# 卸载
fusermount -u /mnt/remote # Linux
umount /mnt/remote # 部分系统
持久化写 /etc/fstab:
user@host:/data /mnt/remote fuse.sshfs _netdev,users,idmap=user,IdentityFile=/home/user/.ssh/id_ed25519,reconnect,ServerAliveInterval=15 0 0
sshfs性能受 SSH 加密和网络 RTT 影响,读写大量小文件很慢。只适合编辑少量文件,别拿它跑数据库或编译。
5. 用 ~/.ssh/config 简化命令
Host db01
HostName 10.0.0.9
User dba
Port 2222
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 30
Host jump
HostName 1.2.3.4
User ops
Host internal-*
ProxyJump jump
配置后直接:
scp file db01:/tmp/
sftp db01
sshfs db01:/data /mnt/remote
ssh internal-web01
ProxyJump 让内网机器通过跳板机直连,不必手动开隧道。
6. 实战场景
6.1 批量拉取日志
mkdir -p /tmp/logs
for h in web01 web02 web03; do
scp -q "$h:/var/log/nginx/access.log" "/tmp/logs/$h-access.log"
scp -q "$h:/var/log/nginx/error.log" "/tmp/logs/$h-error.log"
done
大文件用后台 + 限速:
scp -l 20000 big.tar.gz user@host:/data/ &
6.2 上传前先校验空间与权限
ssh user@host 'df -h /data; ls -ld /data'
scp app.tar.gz user@host:/data/
ssh user@host 'cd /data && sha256sum app.tar.gz'
sha256sum app.tar.gz
6.3 断点续传(scp 不支持,改用 sftp)
sftp user@host
reget big.iso
或直接用 rsync:
rsync -avP --partial big.iso user@host:/data/
6.4 受限环境只用 SFTP 子系统
有些跳板机禁用 shell,只开 sftp:
sftp -b batch.txt user@jump
scp -s user@jump:/path # 强制使用 sftp 协议
6.5 Windows 客户端
- Win10+ 自带
scp/sftp(OpenSSH 客户端功能需在"可选功能"里启用)。 - WinSCP 图形化,支持同步与脚本(
winscp.com /script=...)。 - 路径写法:
scp file.txt user@host:C:/Users/user/(远端路径用正斜杠)。
7. 常见坑
-P与-p完全不同:-P端口,-p保留属性。scp不支持断点续传:大文件断了只能重来,用rsync -P或sftp reget。scp一定全量传输:即使只改了一个字节,也是整个文件重传。- 通配符在本地被展开:
scp host:/data/*.log .中*可能先被本地 shell 处理,路径要用引号包住('host:/data/*.log')。 - OpenSSH 9.0+ 的
scp走 SFTP:~展开和通配行为变化,脚本报错时加-O回退旧协议。 sshfs断线后目录卡死:任何ls都会挂住,必须fusermount -u强卸,挂载时加reconnect。sshfs不保留 SELinux 上下文,写系统目录会出权限问题。- 权限问题:上传后属主是登录用户,需要 root 所属文件时先传
/tmp再sudo mv。 - 私钥权限:
chmod 600,否则报UNPROTECTED PRIVATE KEY FILE。 sftp -b失败不提示:加-v看细节,退出码非 0 要检查。- 中文文件名:终端编码不一致会乱码,
sftp下用-o或先改名。 - 限制目录(chroot)环境:
scp可能因 sftp-server 路径不可用而失败,需管理员配置Subsystem sftp internal-sftp。
8. 速查表
scp file user@host:/tmp/ # 上传
scp user@host:/tmp/file . # 下载
scp -r dir user@host:/data/ # 递归
scp -P 2222 -i key.pem f host:/tmp/ # 端口+密钥
scp -C -l 8000 f host:/tmp/ # 压缩+限速
scp 'host:/data/*.log' ./ # 通配(加引号)
sftp user@host # 交互
sftp -b batch.txt user@host # 批处理
# 交互:ls/cd/lcd/get/put/mget/mput/reget/bye
sshfs user@host:/data /mnt/remote # 挂载
fusermount -u /mnt/remote # 卸载
rsync -avP --partial dir/ host:/data/ # 大目录首选