作为一名长期与服务器打交道的运维工程师,我每天都要在不同机器间传输大量文件。SCP(Secure Copy Protocol)是我最常用的工具之一,它基于SSH协议实现加密传输,既保证了安全性,又具备简单高效的特点。与FTP等传统工具相比,SCP不需要额外配置服务端,只要SSH能连接就能直接使用,这对管理多台服务器的运维人员来说简直是福音。
SCP的核心优势在于:
重要提示:使用SCP前请确保已经配置好SSH免密登录,否则每次操作都需要输入密码。配置方法是在本机执行
ssh-copy-id 用户名@服务器IP,然后输入一次密码即可永久生效。
最基本的SCP上传命令结构如下:
bash复制scp [参数] 本地文件路径 用户名@服务器IP:远程路径
以我日常工作中的典型场景为例,假设需要将本地的app.py上传到172.18.13.90服务器的用户主目录:
bash复制scp app.py cyun@172.18.13.90:~
这里的~符号代表远程用户的主目录,相当于/home/cyun/。这个命令执行后,你会看到类似这样的进度显示:
code复制app.py 100% 156KB 1.5MB/s 00:00
这表示文件已100%传输完成,大小156KB,平均速度1.5MB/s,耗时不到1秒。
当需要传输整个目录时,必须使用-r参数(recursive的缩写)。比如传输myfolder目录:
bash复制scp -r myfolder cyun@172.18.13.90:~
实际工作中我经常遇到需要传输包含大量小文件的目录,这时有几个实用技巧:
压缩后再传输:对于包含数千个小文件的目录,先用tar打包压缩再传输会更高效
bash复制tar czvf myfolder.tar.gz myfolder
scp myfolder.tar.gz cyun@172.18.13.90:~
ssh cyun@172.18.13.90 "tar xzvf ~/myfolder.tar.gz"
限速传输:避免占用全部带宽影响其他服务,使用-l参数限制速度(单位Kbit/s)
bash复制scp -l 512 -r large_folder cyun@172.18.13.90:~
保持文件属性:使用-p保留文件的修改时间、访问时间和权限
bash复制scp -rp myfolder cyun@172.18.13.90:~
如果服务器SSH端口不是默认的22,需要用-P指定(注意是大写P):
bash复制scp -P 2222 app.py cyun@172.18.13.90:~
其他实用参数:
-C:启用压缩传输,适合低带宽环境-q:静默模式,不显示进度和统计信息-v:详细模式,显示调试信息,排查问题时很有用下载操作的命令结构与上传正好相反:
bash复制scp [参数] 用户名@服务器IP:远程文件路径 本地路径
例如下载远程的/tmp/log.txt到当前目录:
bash复制scp cyun@172.18.13.90:/tmp/log.txt .
这里的.代表当前目录。我建议总是明确指定本地路径,避免文件下载到意外位置。
下载目录同样需要-r参数:
bash复制scp -r cyun@172.18.13.90:/home/cyun/myfolder .
处理特殊文件时的注意事项:
ls -a查看screen或tmux运行SCP,防止网络中断导致传输失败SCP本身不支持断点续传,这是它的一个主要局限。对于大文件传输,我有两个替代方案:
方案一:使用rsync
bash复制rsync -Pavz -e "ssh -p 22" cyun@172.18.13.90:/path/to/file .
-P参数显示进度并支持部分传输,-a保持文件属性,-z启用压缩
方案二:分卷压缩传输
bash复制# 远程操作
tar czvf - bigfile | split -b 1G - bigfile.tar.gz.
# 下载分卷
scp cyun@172.18.13.90:bigfile.tar.gz.* .
# 本地合并
cat bigfile.tar.gz.* | tar xzvf -
问题一:Connection refused
code复制ssh: connect to host 172.18.13.90 port 22: Connection refused
可能原因:
问题二:Permission denied
code复制cyun@172.18.13.90: Permission denied (publickey,password).
解决方案:
通过多年实践,我总结了这些提速方法:
启用压缩:特别适合文本文件
bash复制scp -C file cyun@172.18.13.90:~
更换加密算法:默认的aes128-ctr可能不是最快的
bash复制scp -c aes256-gcm@openssh.com bigfile cyun@172.18.13.90:~
并行传输:结合GNU parallel工具
bash复制parallel -j 4 scp {} cyun@172.18.13.90:~/ ::: file1 file2 file3 file4
调整SSH配置:在/etc/ssh/sshd_config中添加:
code复制Ciphers aes128-ctr,aes192-ctr,aes256-ctr
MACs hmac-sha1
敏感文件保护:传输包含敏感信息的文件时,考虑先加密再传输
bash复制gpg -c secretfile && scp secretfile.gpg cyun@172.18.13.90:~
审计跟踪:在服务器上配置SCP日志记录,在/etc/ssh/sshd_config中添加:
code复制Subsystem scp /usr/lib/openssh/sftp-server -l INFO
传输验证:重要文件传输后应该校验MD5
bash复制md5sum local_file
ssh cyun@172.18.13.90 "md5sum remote_file"
SCP最强大的功能之一是支持直接在两台服务器间传输文件,无需经过本地中转:
bash复制scp -3 cyun@source_server:/path/to/file cyun@target_server:~/
-3参数表示通过本地中转,如果两台服务器间网络通畅,可以去掉这个参数让它们直接传输。
在~/.ssh/config中添加服务器配置:
code复制Host myserver
HostName 172.18.13.90
User cyun
Port 22
之后SCP命令可以简化为:
bash复制scp app.py myserver:~
这是我常用的备份脚本片段:
bash复制#!/bin/bash
BACKUP_FILE="backup_$(date +%Y%m%d).tar.gz"
tar czf /tmp/$BACKUP_FILE /important/data
scp /tmp/$BACKUP_FILE backup_server:/backups/
rm /tmp/$BACKUP_FILE
SCP虽然简单,但在实际运维工作中能解决90%的文件传输需求。掌握它的各种技巧可以极大提高工作效率。我建议新手从基础命令开始,逐步尝试高级用法,最终形成适合自己的工作流程。对于更复杂的场景,可以考虑rsync等更专业的工具,但SCP因其简单可靠,始终是我工具箱里的必备利器。