在服务器迁移、部署自动化脚本、或排查”文件传不上去”这类问题时,快速确认 FTP 能不能连通是第一步。很多人习惯装 FileZilla 这类图形工具去试,但在命令行环境下,curl 往往是更轻量、更适合脚本化的选择——一条命令就能验证”能不能连、能不能登录、能不能传”。
本文从最基础的连通测试讲起,覆盖账号登录、被动模式、FTPS 加密、上传下载验证,以及一套可直接放进巡检脚本的一键诊断函数。
一、为什么用 curl 测 FTP
- 几乎全平台内置:Linux / macOS 默认带;Windows 10 及以上也在
PATH中(curl --version验证)。 - 一条命令验证三层:TCP 连通 → 登录认证 → 数据收发,全部覆盖。
- 天然可脚本化:配合退出码(
$?)即可做自动化连通性巡检,比 GUI 工具更适合 CI / 定时任务。
二、准备工作
- 确认 curl 支持 FTP 协议:
curl --version # 输出里 Protocols: 一行须包含 ftp ftps - 备好四项信息:主机地址、端口(默认
21)、用户名、密码。 - 若有防火墙,需确认控制端口 21 及被动端口区间已放行(详见第九节)。
三、基础连通测试(匿名探测)
先不加账号,只验证服务端是否在 21 端口响应:
curl -v ftp://ftp.example.com/
-v(verbose)会打印完整握手过程。看到 220 欢迎语、USER anonymous 即说明网络与控制端口是通的;若卡在 “Trying … connected” 之前,则是网络/防火墙不通。
只关心”连没连上”时,
curl的退出码最有价值:0=成功,非0=失败。脚本里直接if curl ...; then ...即可。
四、带账号登录
curl -u 用户名:密码 ftp://ftp.example.com/
或把凭据放在 URL 里(不推荐,密码会进历史记录):
curl ftp://用户名:密码@ftp.example.com/
若密码含 @ : / & 等特殊字符,必须用 URL 编码(@→%40,:→%3A)。更安全的写法是用 -u 后留空密码让 curl 交互提示,或借助 .netrc 文件。
安全提醒:命令行里的
-u 用户:密码会被同一台机器的其他用户通过ps看到。生产环境务必改用~/.netrc(权限设为600)或环境变量传参。
五、只测连通、不传数据
只想确认”到 USER/PASS 这一步是否通”,不想真正拉列表时,用超时限制 + verbose:
curl --connect-timeout 10 --max-time 20 -v ftp://用户名:密码@ftp.example.com/
--connect-timeout:建立 TCP 连接的最长等待(测网络用)。--max-time:整个命令总超时,避免卡死。
六、被动模式(PASV)与主动模式
FTP 默认用被动模式,数据连接由客户端向服务端发起,最适合穿越客户端防火墙:
curl -P - ftp://用户名:密码@ftp.example.com/ # 被动模式(默认即可)
curl --ftp-port 0.0.0.0 ftp://.../ # 主动模式(PORT)
绝大多数现代网络下保持默认的被动模式即可。若服务端强制主动模式而你又处于 NAT 后,才可能需要在路由器放行高位端口。
七、FTPS(加密 FTP)
很多合规场景要求加密传输。curl 同时支持隐式与显式 FTPS:
# 显式加密(服务器通常在 21 端口升级到 TLS)
curl --ftp-ssl ftp://用户名:密码@ftp.example.com/
# 隐式加密(专用端口 990)
curl ftps://用户名:密码@ftp.example.com/
证书自签时,仅测试可临时跳过校验:
curl -k --ftp-ssl ftp://用户名:密码@ftp.example.com/
-k会关闭证书校验,仅限排错环境,生产脚本请勿长期使用,否则失去加密意义。
八、列目录 / 下载 / 上传验证
连通和登录都通后,再验一下数据通道是否真能收发:
# 列出根目录
curl -u 用户:密码 ftp://ftp.example.com/
# 下载一个文件到本地
curl -u 用户:密码 ftp://ftp.example.com/remote/file.zip -o ./file.zip
# 上传本地文件
curl -T ./local.txt -u 用户:密码 ftp://ftp.example.com/incoming/
# 上传并显示进度/结果
curl -T ./local.txt -u 用户:密码 --ftp-create-dirs ftp://ftp.example.com/incoming/sub/
--ftp-create-dirs 会在服务端自动创建不存在的目录,部署脚本里很实用。
九、防火墙与端口要点
| 模式 | 控制连接 | 数据连接 | 放行建议 |
|---|---|---|---|
| 被动 PASV | 客户端→服务端 21 |
客户端→服务端 被动端口区间(如 30000–31000) | 服务端需开放该区间;客户端一般无需特殊配置 |
| 主动 PORT | 客户端→服务端 21 |
服务端→客户端 高位端口(>1023) | 客户端防火墙需放行入站高位端口,NAT 下易失败 |
企业网里”能登不能列/不能传”,九成是被动端口区间没放行。
十、常见错误速查表
| 现象 / 报错 | 含义 | 排查方向 |
|---|---|---|
Could not resolve host |
域名解析失败 | DNS / 域名拼写 |
Failed to connect: Connection refused |
端口无服务 | IP/端口错、FTP 未启动、被防火墙拦 |
Connection timed out |
网络不可达 | 路由、安全组、白名单 IP |
530 Login incorrect |
账号/密码错或被禁 | 凭据、账号状态、IP 是否被限 |
227 Entering Passive Mode 后卡住 |
被动端口不通 | 放行被动端口区间 |
425 Can't open data connection |
数据通道建立失败 | 被动/主动模式与防火墙不匹配 |
SSL certificate problem |
证书不受信 | 加 -k 临时测,或配置 CA |
十一、一键诊断脚本
把下面函数放进 ~/.bashrc,随时 ftp_check 主机 用户 密码 跑一遍连通性体检:
ftp_check() {
local host="$1" user="$2" pass="$3"
echo "==> 测试 FTP 连通: $host"
if curl --connect-timeout 10 --max-time 25 -sS -u "$user:$pass" \
"ftp://$host/" >/dev/null; then
echo "[OK] 连通 + 登录 + 列目录 全部成功"
return 0
else
echo "[FAIL] 失败,退出码 $?;加 -v 重试看握手细节"
return 1
fi
}
# 用法:ftp_check ftp.example.com myuser mypass
十二、小结
用 curl 测 FTP,核心就三层:网络通不通(-v 看 220) → 账号对不对(-u 看 230 Login successful) → 数据能不能传(列目录 / 上传下载)。配合 --connect-timeout、--max-time 和退出码,就能把人工试探变成一行可纳入监控的脚本。遇到”能登不能传”,优先怀疑被动端口区间的防火墙放行。
本文命令均为标准 curl 语法,Linux / macOS / Windows(10+)通用。














暂无评论内容