ZeroTermux ftp 命令完整指南:从客户端交互到内置 FTP 服务器实战
ZeroTermux ftp 命令完整指南:从客户端交互到内置 FTP 服务器实战
本篇技术指南以 ZeroTermux 内置命令手册 ftp.md 为骨架,系统讲解 Linux ftp 命令的语法、选项、参数与全套交互式子命令,并结合作品中内置的 FTP 服务器源码(com.termux.zerocore.ftp 包),打通"客户端命令 ↔ 服务端处理"的完整链路。读完本文,你将掌握用 ftp 命令在本地机与远程机之间上传、下载、管理文件的全部实操方法,同时理解 ZeroTermux 内置 FTP 服务在认证、端口、目录隔离(chroot)上的底层行为,做到"会敲命令,也懂原理"。
ftp 命令是什么:文件系统相关的网络传输工具
ftp 命令用于设置文件系统相关功能。FTP 服务器在网上较为常见,Linux ftp 命令的功能是用命令行的方式来控制在本地机和远程机之间传送文件。在 ZeroTermux 中,这一命令手册被收录在 app/src/main/assets/cmd/ 目录下,与 apt-get、ssh、curl 等数百份命令文档共同构成应用内置的 Linux 命令速查库,方便用户直接在终端内查阅。
而要让这些命令真正"有服务端可连",ZeroTermux 同时内置了一套完整的 FTP 服务器实现(源自 SwiFTP 架构),源码位于 app/src/main/java/com/termux/zerocore/ftp/。客户端一侧敲下的每个命令动词,最终都会由服务端对应的命令处理器(Cmd* 类)响应,这一点在本文第 7 节会有详细对照。
语法与选项
ftp 命令的基本语法为:
ftp(选项)(参数)
选项说明
| 选项 | 作用 |
|---|---|
-d |
详细显示指令执行过程,便于排错或分析程序执行的情况 |
-i |
关闭互动模式,不询问任何问题(常用于脚本批量操作,配合 mget/mput 可避免逐个确认) |
-g |
关闭本地主机文件名称支持特殊字符的扩充特性(即禁用文件名通配符扩展) |
-n |
不使用自动登录(跳过启动时的 .netrc 自动登录流程,改用交互式 USER/PASS 登录) |
-v |
显示指令执行过程(冗长模式,输出每次命令的详细回显) |
参数说明
主机:指定要连接的 FTP 服务器的主机名或 IP 地址。例如连接本地局域网内一台设备:
ftp 192.168.1.100
进入交互模式:全套内部命令
连接成功后即进入 ftp> 交互提示符。以下命令构成了 FTP 交互会话的核心操作集(均完整继承自 ftp.md 手册):
ftp> ascii # 设定以ASCII方式传送文件(缺省值)
ftp> bell # 每完成一次文件传送,报警提示.
ftp> binary # 设定以二进制方式传送文件.
ftp> bye # 终止主机FTP进程,并退出FTP管理方式.
ftp> case # 当为ON时,用MGET命令拷贝的文件名到本地机器中,全部转换为小写字母.
ftp> cd # 同UNIX的CD命令.
ftp> cdup # 返回上一级目录.
ftp> chmod # 改变远端主机的文件权限.
ftp> close # 终止远端的FTP进程,返回到FTP命令状态, 所有的宏定义都被删除.
ftp> delete # 删除远端主机中的文件.
ftp> dir [remote-directory] [local-file] # 列出当前远端主机目录中的文件.如果有本地文件,就将结果写至本地文件.
ftp> get [remote-file] [local-file] # 从远端主机中传送至本地主机中.
ftp> help [command] # 输出命令的解释.
ftp> lcd # 改变当前本地主机的工作目录,如果缺省,就转到当前用户的HOME目录.
ftp> ls [remote-directory] [local-file] # 同DIR.
ftp> macdef # 定义宏命令.
ftp> mdelete [remote-files] # 删除一批文件.
ftp> mget [remote-files] # 从远端主机接收一批文件至本地主机.
ftp> mkdir directory-name # 在远端主机中建立目录.
ftp> mput local-files # 将本地主机中一批文件传送至远端主机.
ftp> open host [port] # 重新建立一个新的连接.
ftp> prompt # 交互提示模式.
ftp> put local-file [remote-file] # 将本地一个文件传送至远端主机中.
ftp> pwd # 列出当前远端主机目录.
ftp> quit # 同BYE.
ftp> recv remote-file [local-file] # 同GET.
ftp> rename [from] [to] # 改变远端主机中的文件名.
ftp> rmdir directory-name # 删除远端主机中的目录.
ftp> send local-file [remote-file] # 同PUT.
ftp> status # 显示当前FTP的状态.
ftp> system # 显示远端主机系统类型.
ftp> user user-name [password] [account] # 重新以别的用户名登录远端主机.
ftp> ? [command] # 同HELP. [command]指定需要帮助的命令名称。如果没有指定 command,ftp 将显示全部命令的列表。
ftp> ! # 从 ftp 子系统退出到外壳。
高频命令速记
- 目录导航:
cd(远端)、lcd(本地)、cdup、pwd组合使用,可在会话中自由切换两侧工作目录; - 文件列表:
ls/dir列出远端目录,dir可附加本地文件名把结果写入本地文件; - 单文件传输:
get(下载)、put(上传),recv与send分别是二者的同义别名; - 批量传输:
mget(批量下载)、mput(批量上传)、mdelete(批量删除),配合-i选项可跳过逐个确认;case开启时mget拷入的文件名自动转为小写; - 传输模式:
ascii适合文本文件(默认值),binary适合压缩包、图片、可执行文件等二进制数据,乱码时先检查此项; - 远端管理:
mkdir/rmdir/delete/rename/chmod完成远端文件与目录的增删改; - 会话管理:
open重建连接、close终止远端进程、bye/quit退出、user重新登录、!临时回到本机 shell、?查看帮助。
关闭 FTP 连接
在 ftp> 提示符下,以下三个命令均可关闭连接并退出:
bye
exit
quit
其中 bye 与 quit 等价,exit 在多数实现中同样生效。建议养成传输完成后显式关闭连接的习惯,避免占用服务端会话资源——ZeroTermux 内置服务端会为每个连接创建独立的会话线程,超量悬挂连接会占用系统资源(详见下文服务端实现)。
下载文件
ftp> get readme.txt # 下载 readme.txt 文件
ftp> mget *.txt # 下载
get readme.txt:将远端当前目录下的readme.txt下载到本地当前目录;mget *.txt:按通配符批量下载多个.txt文件;若未加-i启动,每个文件都会询问确认(prompt命令可切换该交互确认行为)。
上传文件
ftp> put /path/readme.txt # 上传 readme.txt 文件
ftp> mput *.txt # 可以上传多个文件
put /path/readme.txt:将本地指定路径的文件上传到远端当前目录(文件名保持原样,如需改名可在命令末尾追加远端文件名);mput *.txt:批量上传多个文件,同样受prompt交互模式影响。
深入源码:ZeroTermux 内置 FTP 服务器如何响应这些命令
前面介绍的客户端命令,其服务端对应实现就藏在 com.termux.zerocore.ftp 包中。理解服务端行为能帮你更准确地使用客户端命令。
命令分发表:客户端动词到服务端处理器
在 FtpCmd.java 中,服务端维护了一张完整的命令映射表 cmdClasses,客户端发出的命令动词(大写化后)会被逐一匹配并分发到对应的 Cmd* 处理器:
| 客户端命令 | 服务端处理器 | 说明 |
|---|---|---|
| USER / PASS | CmdUSER.java / CmdPASS | 登录认证 |
| CWD / CDUP / PWD / MKD / RMD | CmdCWD / CmdCDUP / CmdPWD / CmdMKD / CmdRMD | 目录操作(XCUP、XPWD、XMKD、XRMD 为兼容别名) |
| LIST / NLST / MLSD / MLST | CmdLIST / CmdNLST / CmdMLSD / CmdMLST | 目录列表,对应客户端的 ls/dir |
| RETR / STOR / APPE | CmdRETR / CmdSTOR / CmdAPPE | 下载 / 上传 / 追加写入,对应 get/put |
| DELE / RNFR / RNTO | CmdDELE / CmdRNFR / CmdRNTO | 删除 / 重命名,对应 delete/rename |
| TYPE / SIZE / REST / RANG | CmdTYPE / CmdSIZE / CmdREST / CmdRANG | 传输模式 / 文件大小 / 断点续传 |
| PASV / PORT | CmdPASV / CmdPORT | 数据连接模式(被动 / 主动) |
| SYST / FEAT / HASH / MFMT / MDTM / OPTS / SITE / NOOP / QUIT | 同名 Cmd 类 | 系统信息、能力协商、哈希、时间戳、空操作、退出 |
分发逻辑由 FtpCmd.java 中的 dispatchCommand() 完成:先按空格拆分输入行取动词,再查表反射实例化处理器,最后按登录状态决定是否放行——未登录时仅允许 USER、PASS、QUIT 以及匿名可用的只读命令(allowedCmdsWhileAnonymous 列表)。
一次完整会话的服务端处理链路
从源码结构可以梳理出完整的服务端调用链:
- 监听:FsService.java 的
setupListener()创建ServerSocket并绑定端口(端口号来自SaveDataZeroEngine.getPort()); - 接入:TcpListener.java 在
accept()上循环等待新连接,每接一个客户端就创建一个 SessionThread.java 会话线程并注册到服务; - 会话:
SessionThread.run()先发送220欢迎横幅,再进入readLine()主循环,把每一行客户端指令交给FtpCmd.dispatchCommand()处理,处理结果通过命令通道回写; - 数据通道:
PASV/PORT建立数据连接后,RETR(下载)、STOR(上传)、LIST(列表)等命令通过 SessionThread.java 的openDataSocket()打开数据流,以 64KB 分块(DATA_CHUNK_SIZE = 65536)执行文件 I/O。
认证、端口与目录隔离的底层细节
- 默认端口:
SaveDataZeroEngine中默认端口为 2121(SaveDataZeroEngine.java),而不是传统 FTP 的 21 端口;用户名、密码、根目录、端口均通过SharedPreferences(键ftpUserName、ftpPassWord、ftpChroot、ftpPort)持久化配置; - 认证流程:CmdPASS.java 要求先发
USER再发PASS;用户名anonymous走只读访客通道,普通用户则与 FtpUser.java 中保存的密码比对,失败会sleep 1 秒以对抗暴力破解,且累计失败超过 3 次(MAX_AUTH_FAILS = 3)自动断开会话; - chroot 目录隔离:FtpCmd.java 的
violatesChroot()会对每次文件访问做规范路径(canonical path)前缀校验,任何试图越出用户根目录(chroot)的路径都会被拒绝——这正是客户端cd ../..无法跳出限制目录的服务端保障; - 连接前提:服务端会检查设备处于 WiFi / 以太网 / WiFi 热点 / USB RNDIS 任一本地网络环境(FsService.java),并持有 Wi-Fi 锁与唤醒锁以保障长会话稳定。
端到端实战:用 ftp 命令连接 ZeroTermux 内置服务器
将客户端命令与服务端实现串起来,一次完整的传输流程如下:
# 1. 连接(服务端监听端口默认为 2121)
ftp 192.168.1.100 2121
# 2. 登录(对应服务端 CmdUSER / CmdPASS 校验)
ftp> user ftp
ftp> pass <你的密码>
# 3. 查看远端目录(对应服务端 CmdLIST / CmdNLST)
ftp> ls
# 4. 切换为二进制模式,下载文件(对应服务端 CmdTYPE / CmdRETR)
ftp> binary
ftp> get backup.zip
# 5. 上传文件(对应服务端 CmdSTOR)
ftp> put /sdcard/notes.txt
# 6. 退出(对应服务端 CmdQUIT)
ftp> bye
需要说明的是:以上服务端行为均以当前仓库 app/src/main/java/com/termux/zerocore/ftp/ 中的实现为准,具体端口、账户与根目录以你在应用内配置为准;实际使用时请先在设备端确认 FTP 服务已启动,并将主机地址换成设备当前局域网 IP。
小结
ftp 命令是 Linux 下最经典的跨主机文件传输工具之一:-d/-i/-g/-n/-v 五个选项控制行为,交互模式下的 get/put/mget/mput/cd/lcd/dir/delete/rename 等子命令覆盖导航、传输与管理的全部场景。在 ZeroTermux 中,这套命令手册既有 app/src/main/assets/cmd/ftp.md 的即时查阅支持,又有 FsService.java、FtpCmd.java 等源码实现的真实服务端可连可测。掌握客户端命令语义,再对照服务端分发与认证、chroot 隔离机制,即可在 ZeroTermux 环境中高效、安全地完成文件传输任务。