Linux sftp命令详解

SFTP(SSH File Transfer Protocol)是SSH协议的一部分,提供安全的文件传输功能。与传统的FTP不同,SFTP通过加密的SSH连接传输数据,确保文件传输的安全性。

核心优势:加密传输 | SSH集成 | 断点续传 | 目录操作 | 文件权限保持

核心特性

加密传输

通过SSH加密所有数据传输,防止信息泄露

SSH集成

使用SSH认证机制,支持密钥和密码认证

双向操作

支持完整的文件系统操作(上传、下载、删除等)

安装与检查

Ubuntu/Debian
# 检查是否已安装
which sftp

# 通常包含在openssh-client中
sudo apt update
sudo apt install openssh-client
CentOS/RHEL
# 检查安装
rpm -qa | grep openssh

# 安装客户端
sudo yum install openssh-clients
服务器端
# 安装SSH服务器(已包含SFTP)
sudo apt install openssh-server  # Ubuntu
sudo yum install openssh-server  # CentOS

# 启动SSH服务
sudo systemctl start sshd
sudo systemctl enable sshd
macOS
# macOS已内置sftp
sftp -V

# 如果需要更新
brew install openssh

基本语法

sftp [选项] [用户名@]主机名[:路径]
sftp [选项] [用户名@]主机名[:路径] [本地路径]

常用选项

选项 描述 示例
-P 端口 指定SSH端口(注意大写P) -P 2222
-i 密钥文件 指定身份密钥文件 -i ~/.ssh/id_rsa
-b 批处理文件 从文件读取批处理命令 -b commands.txt
-v 详细模式(显示调试信息) -v
-q 安静模式(不显示进度信息) -q
-B 缓冲区大小 指定传输缓冲区大小 -B 32768
-R 重试次数 连接失败时的重试次数 -R 3
-o SSH选项 设置SSH选项 -o ConnectTimeout=30

连接与认证

基础连接 密码认证连接

使用用户名密码连接远程服务器:

# 标准连接(使用默认端口22)
sftp username@server.example.com

# 连接时指定远程目录
sftp username@server.example.com:/home/username/

# 连接并切换到指定本地目录
sftp username@server.example.com ~/local_dir
密钥认证 SSH密钥连接

使用SSH密钥文件连接(无需密码):

# 使用指定密钥文件
sftp -i ~/.ssh/id_rsa username@server.example.com

# 指定非标准端口
sftp -i ~/.ssh/id_rsa -P 2222 username@server.example.com

# 使用配置文件中的主机别名
sftp myserver  # 需在~/.ssh/config中配置

SFTP会话命令

交互式会话操作
# 连接成功后进入sftp>提示符
sftp> help                 # 显示可用命令
sftp> pwd                 # 显示远程当前目录
sftp> lpwd                # 显示本地当前目录
sftp> ls                  # 列出远程目录内容
sftp> lls                 # 列出本地目录内容
sftp> cd /remote/path     # 切换远程目录
sftp> lcd /local/path     # 切换本地目录
sftp> mkdir newdir        # 创建远程目录
sftp> lmkdir newdir       # 创建本地目录
sftp> rm file.txt         # 删除远程文件
sftp> rmdir empty_dir     # 删除远程空目录
sftp> rename old new      # 重命名远程文件
sftp> chmod 755 file.sh   # 修改远程文件权限
sftp> chown user file     # 修改远程文件所有者
sftp> df                  # 显示远程磁盘使用情况
sftp> !command            # 执行本地shell命令
sftp> exit                # 退出sftp会话
sftp> quit                # 退出sftp会话

文件传输操作

上传文件 本地到远程
# 上传单个文件
sftp> put local_file.txt
sftp> put local_file.txt remote_file.txt  # 重命名上传

# 上传多个文件
sftp> put file1.txt file2.txt file3.txt

# 使用通配符上传
sftp> put *.txt
sftp> put *.pdf /remote/path/

# 上传整个目录(-r递归)
sftp> put -r local_directory/

# 保留文件时间戳和权限
sftp> put -p important_file.txt
下载文件 远程到本地
# 下载单个文件
sftp> get remote_file.txt
sftp> get remote_file.txt local_name.txt  # 重命名下载

# 下载多个文件
sftp> get file1.txt file2.txt file3.txt

# 使用通配符下载
sftp> get *.log
sftp> get /var/log/*.log

# 下载整个目录(-r递归)
sftp> get -r remote_directory/

# 恢复下载(断点续传)
sftp> reget large_file.zip
sftp> reput large_file.zip

批处理模式

创建批处理文件进行自动化传输
# 创建批处理文件 commands.txt
echo "cd /remote/uploads" > commands.txt
echo "put file1.txt" >> commands.txt
echo "put file2.txt" >> commands.txt
echo "mkdir backup" >> commands.txt
echo "put -r backup_files/ backup/" >> commands.txt
echo "bye" >> commands.txt

# 执行批处理
sftp -b commands.txt username@server.example.com

# 带密码自动登录(不推荐生产环境使用)
sshpass -p 'password' sftp -b commands.txt user@host
自动化备份脚本示例
#!/bin/bash
# auto_backup.sh - 自动备份脚本

REMOTE_USER="backupuser"
REMOTE_HOST="backup.server.com"
REMOTE_DIR="/backup/$(hostname)"
LOCAL_DIR="/data/backup"
BACKUP_FILE="backup-$(date +%Y%m%d).tar.gz"

# 1. 创建本地备份
tar -czf $LOCAL_DIR/$BACKUP_FILE /important/data/

# 2. 创建sftp批处理命令
cat > /tmp/sftp_cmds.txt << EOF
cd $REMOTE_DIR
mkdir -p $(date +%Y)/$(date +%m)
cd $(date +%Y)/$(date +%m)
put $LOCAL_DIR/$BACKUP_FILE
ls -la
bye
EOF

# 3. 执行sftp传输
sftp -b /tmp/sftp_cmds.txt $REMOTE_USER@$REMOTE_HOST

# 4. 清理临时文件
rm /tmp/sftp_cmds.txt
echo "Backup completed: $BACKUP_FILE"

SSH配置优化

SSH客户端配置(~/.ssh/config)
# SFTP连接优化配置
Host myserver
    HostName server.example.com
    User username
    Port 2222
    IdentityFile ~/.ssh/id_rsa
    Compression yes
    ServerAliveInterval 60
    ServerAliveCountMax 3
    TCPKeepAlive yes
    # SFTP特定优化
    RekeyLimit 1G
    # 连接复用
    ControlMaster auto
    ControlPath ~/.ssh/%r@%h:%p
    ControlPersist 10m

Host backup-*
    User backup
    IdentityFile ~/.ssh/backup_key
    # 限制为SFTP only
    ForceCommand internal-sftp
    ChrootDirectory /backup
    PasswordAuthentication no
    AllowTcpForwarding no
    PermitTunnel no
    X11Forwarding no

高级技巧

# 1. 限速传输(需要lftp配合)
# 安装lftp: sudo apt install lftp
lftp sftp://user:pass@host -e "set net:limit-rate 102400; put largefile.iso; exit"

# 2. 并行传输多个文件
cat > upload.txt << EOF
put file1.txt
put file2.txt
put file3.txt
EOF
sftp -b upload.txt user@host &

# 3. 监控传输进度
sftp user@host << EOF
progress
put large_file.iso
EOF

# 4. 使用代理服务器
sftp -o "ProxyCommand=nc -X connect -x proxy:8080 %h %p" user@host

# 5. 强制IPv4或IPv6
sftp -4 user@host    # 强制IPv4
sftp -6 user@host    # 强制IPv6

# 6. 调试连接问题
sftp -v -v -v user@host 2>&1 | tee debug.log

# 7. 使用expect脚本自动输入密码(不推荐生产环境)
#!/usr/bin/expect
spawn sftp user@host
expect "password:"
send "your_password\r"
expect "sftp>"
send "put file.txt\r"
expect "sftp>"
send "exit\r"

SFTP vs SCP

特性对比 SFTP SCP
协议 SSH文件传输协议 安全复制协议
交互性 交互式命令行,支持完整文件操作 仅传输文件,无交互
断点续传 支持(reget/reput) 不支持
目录操作 支持ls、cd、mkdir等 不支持
文件权限 支持chmod、chown 仅保留基本权限
传输速度 稍慢(协议开销) 较快(简单协议)
适用场景 交互式管理、复杂操作、大文件传输 简单文件复制、脚本自动化

安全性配置

密钥管理
# 生成SSH密钥对
ssh-keygen -t rsa -b 4096 -f ~/.ssh/sftp_key

# 设置密钥权限
chmod 600 ~/.ssh/sftp_key
chmod 644 ~/.ssh/sftp_key.pub

# 上传公钥到服务器
ssh-copy-id -i ~/.ssh/sftp_key.pub user@host
服务器配置
# /etc/ssh/sshd_config
Subsystem sftp internal-sftp

# 限制用户只能使用SFTP
Match Group sftpusers
    ChrootDirectory /home/%u
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no

常见问题解决

连接问题
# 错误: Connection refused
# 解决方案:
# 1. 检查SSH服务状态
sudo systemctl status sshd

# 2. 检查防火墙
sudo ufw allow 22/tcp
# 或
sudo firewall-cmd --add-service=ssh --permanent

# 3. 检查SELinux
getenforce
# 如果是Enforcing模式
sudo setsebool -P ssh_chroot_full_access on
权限错误
# 错误: Permission denied
# 可能原因:
# 1. 密钥文件权限太开放
chmod 600 ~/.ssh/id_rsa

# 2. Chroot目录权限问题
# Chroot目录必须为root所有且权限为755
sudo chown root:root /chroot
sudo chmod 755 /chroot

# 3. 用户家目录权限
chmod 755 ~
性能优化
# 传输速度慢的优化
# 1. 启用压缩
sftp -C user@host

# 2. 增大缓冲区
sftp -B 65536 user@host

# 3. 使用更快的加密算法
# 在~/.ssh/config中添加:
Ciphers aes128-ctr,aes192-ctr,aes256-ctr
日志调试
# 启用详细日志
sftp -v user@host 2>&1 | tee sftp.log

# 服务器端日志
sudo tail -f /var/log/auth.log
# 或
sudo journalctl -u sshd -f

# 增加SSH日志级别
# 在sshd_config中添加:
LogLevel VERBOSE

实用场景

数据库备份
# 备份MySQL数据库并传输
mysqldump -u root -p database | gzip > backup.sql.gz
sftp backup@server << EOF
cd /backup/mysql
put backup.sql.gz
ls -lh *.gz
EOF
网站部署
# 部署网站文件
tar -czf site.tar.gz public_html/
sftp deploy@webserver << EOF
cd /var/www
put site.tar.gz
!tar -xzf site.tar.gz
rm site.tar.gz
chmod -R 755 public_html
EOF
云存储同步
# 同步到云服务器
sftp -b - user@cloud-storage << 'EOF'
cd /storage/backup
mkdir -p $(date +%Y-%m-%d)
cd $(date +%Y-%m-%d)
put -r /local/data/
EOF
服务器迁移
# 迁移网站数据
sftp oldserver << EOF
get -r /var/www/html /tmp/old_site
EOF

sftp newserver << EOF
cd /var/www
put -r /tmp/old_site
chown -R www-data:www-data html
EOF
最佳实践
  • 始终使用SSH密钥认证,避免密码传输
  • 配置~/.ssh/config简化连接命令
  • 大文件传输使用-C启用压缩
  • 定期更换SSH密钥,增强安全性
  • 使用批处理模式进行自动化任务
  • 传输前使用ls确认目录位置
  • 重要操作前先做测试,使用!command执行本地检查