scp / sftp / sshfs —— 跨机拷文件

运维工具手册 03-文件与传输 5.3 KB 原文

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. 常见坑

  1. -P 与 -p 完全不同:-P 端口,-p 保留属性。
  2. scp 不支持断点续传:大文件断了只能重来,用 rsync -P 或 sftp reget。
  3. scp 一定全量传输:即使只改了一个字节,也是整个文件重传。
  4. 通配符在本地被展开:scp host:/data/*.log . 中 * 可能先被本地 shell 处理,路径要用引号包住('host:/data/*.log')。
  5. OpenSSH 9.0+ 的 scp 走 SFTP:~ 展开和通配行为变化,脚本报错时加 -O 回退旧协议。
  6. sshfs 断线后目录卡死:任何 ls 都会挂住,必须 fusermount -u 强卸,挂载时加 reconnect。
  7. sshfs 不保留 SELinux 上下文,写系统目录会出权限问题。
  8. 权限问题:上传后属主是登录用户,需要 root 所属文件时先传 /tmp 再 sudo mv。
  9. 私钥权限:chmod 600,否则报 UNPROTECTED PRIVATE KEY FILE。
  10. sftp -b 失败不提示:加 -v 看细节,退出码非 0 要检查。
  11. 中文文件名:终端编码不一致会乱码,sftp 下用 -o 或先改名。
  12. 限制目录(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/   # 大目录首选
scp / sftp / sshfs —— 跨机拷文件 - 知识库 - 起航社区