curl--use-ascii(-B)选项详解:FTP/TFTP 文本传输模式的完整指南
【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl
本篇技术指南围绕 curl 命令行的--use-ascii(短选项-B)展开,系统讲解该选项在 FTP、TFTP 与 LDAP 等协议中开启 ASCII(文本)传输模式的作用机制、与 URL 内置扩展(;type=A、;mode=netascii)的关系、在 Win32 平台下对标准输出的特殊影响,并结合 curl 源码(lib/ftp.c、lib/tftp.c、lib/setopt.c)与命令行参数解析实现(src/tool_getparam.c)揭示其底层实现原理。读完本文,你将能够准确判断何时使用--use-ascii、如何通过 URL 后缀等效开启 ASCII 模式,以及它与--crlf、--data-ascii等关联选项的协同关系。
一、选项总览:-B, --use-ascii
--use-ascii是 curl 内置的布尔型开关选项,其官方定义如下(见 docs/cmdline-opts/use-ascii.md):
| 属性 | 值 |
|---|---|
| 短选项 | -B |
| 长选项 | --use-ascii |
| 帮助文本 | Use ASCII/text transfer |
| 适用协议 | FTP、LDAP、TFTP |
| 分类 | ftp、output、ldap、tftp |
| 引入版本 | 5.0(极早期版本即已存在) |
| 取值类型 | boolean(布尔开关) |
| 默认值 | 关闭(false) |
该选项在 curl 命令行参数表中的注册代码位于 src/tool_getparam.c:
{"use-ascii", ARG_BOOL, 'B', C_USE_ASCII},ARG_BOOL意味着它同时支持--no-use-ascii形式来显式关闭(布尔选项的通用反转语法),在 src/tool_getparam.c 中,解析结果被直接写入全局配置结构体:
case C_USE_ASCII: /* --use-ascii */ config->use_ascii = toggle;该字段定义于 src/tool_cfgable.h:
BIT(use_ascii); /* select ASCII or text transfer */而 src/tool_listhelp.c 中的帮助条目则与文档中的 Help 文本保持一致,供curl --help与curl --manual输出使用。
基本用法
# 通过 FTP 以 ASCII 模式下载文件 curl -B ftp://example.com/README # 等价的长选项写法 curl --use-ascii ftp://example.com/README # 显式关闭(虽然默认就是关闭) curl --no-use-ascii ftp://example.com/README文档给出的规范示例即为-B ftp://example.com/README(见 docs/cmdline-opts/use-ascii.md)。
二、FTP 协议下的 ASCII 模式
2.1 行为含义
在 FTP 协议中,文件传输分为 ASCII 与二进制(IMAGE)两种模式。ASCII 模式下,客户端与服务器之间的换行符会按 RFC 959 规范进行转换(LF 与 CRLF 相互映射);二进制模式则对字节流不做任何改写,适合图片、压缩包、可执行文件等。
curl 文档明确说明:对于 FTP,也可以通过使用以;type=A结尾的 URL 来等效开启 ASCII 模式。即下面两条命令行为等价:
curl -B ftp://example.com/README curl "ftp://example.com/README;type=A"同理,;type=I用于强制二进制模式,;type=D用于请求目录列表。
2.2 源码实现:type_url_check()
URL 后缀;type=<typecode>的解析实现在 lib/ftp.c 的type_url_check()函数中:
static void type_url_check(struct Curl_easy *data, struct FTP *ftp) { size_t len = strlen(ftp->path); /* FTP URLs support an extension like ";type=<typecode>" that * we will try to get now! */ if((len >= 7) && !memcmp(&ftp->path[len - 7], ";type=", 6)) { char *type = &ftp->path[len - 7]; char command = Curl_raw_toupper(type[6]); *type = 0; /* cut it off */ switch(command) { case 'A': /* ASCII mode */ >my_setopt_long(curl, CURLOPT_TRANSFERTEXT, config->use_ascii);而 lib/setopt.c 中的选项处理代码说明了它的历史沿革与最终落点:
case CURLOPT_TRANSFERTEXT: /* * This option was previously named 'FTPASCII'. Renamed to work with * more protocols than merely FTP. * * Transfer using ASCII (instead of BINARY). */ s->prefer_ascii = enabled; break;关键信息有两点:
- 该选项前身名为
FTPASCII,后来为了支持 FTP 之外的协议而改名为TRANSFERTEXT——这正是它同时适用于 TFTP 的原因; - 它最终把
prefer_ascii状态位写入 easy handle 的运行时状态(s->prefer_ascii)。
2.4 对 FTP 会话流程的实际影响
prefer_ascii在 FTP 状态机中驱动TYPE A/TYPE I命令的发送:
- 在获取文件信息(
SIZE)之前,lib/ftp.c 会先调用ftp_nb_type()设置正确的传输类型,因为“某些服务器对不同的模式返回不同的文件大小”,必须先把类型设对再去取 SIZE; - 在正式传输前同样会通过
ftp_nb_type(data, ftpc, ftp, prefer_ascii, ...)发出TYPE A或TYPE I命令(见 lib/ftp.c 与 lib/ftp.c); - 在数据传输后的换行处理上,lib/ftp.c 的注释揭示了 ASCII 模式与
--crlf选项的协作关系:当crlf或prefer_ascii被置位时,curl 会在数据流上执行 CRLF 转换(maybe CRLF conv),反之则不做转换(no conversion)。
从源码结构看,ASCII 模式在 FTP 上既影响控制通道的TYPE命令协商,也影响数据通道的换行符转换,是贯穿 FTP 会话全程的模式标志。
三、TFTP 协议下的 netascii 模式
3.1 行为含义
TFTP 协议定义了三种传输模式:netascii(文本)、octet(二进制,即 8 位原始字节)、mail(已废弃)。curl 文档说明:对于 TFTP,也可以通过使用以;mode=netascii结尾的 URL 来等效开启 ASCII 模式:
curl -B tftp://example.com/README curl "tftp://example.com/README;mode=netascii"3.2 源码实现
TFTP 的 URL 后缀解析位于 lib/tftp.c:
/* TFTP URLs support a trailing ";mode=netascii" or ";mode=octet" */ if((len >= 14) && !memcmp(&path[len - 14], ";mode=netascii", 14)) { ... } else if((len >= 11) && !memcmp(&path[len - 11], ";mode=octet", 11)) { ... }而模式选择发生在发送第一个请求包(RRQ/WRQ)之前,lib/tftp.c 中的tftp_send_first()函数:
static CURLcode tftp_send_first(struct tftp_conn *state, tftp_event_t event) { size_t sbytes; ssize_t senddata; const char *mode = "octet"; char *filename; ... /* Set ASCII mode if -B flag was used */ if(data->state.prefer_ascii) mode = "netascii";这段代码与文档一一对应:默认模式是octet;一旦-B被使用(prefer_ascii为真),请求包中携带的模式就切换为netascii。模式枚举定义在 lib/tftp.c:
TFTP_MODE_NETASCII = 0,TFTP 的 netascii 模式同样包含换行符规范化语义:发送方把\n转换为\r\n(并处理\r后跟\n或\0的特殊情况),接收方做反向转换。因此-B在 TFTP 上适用于纯文本文件的传输,而二进制文件必须使用默认的octet模式。
四、LDAP 与 Win32 平台的文本模式输出
4.1 LDAP 协议
文档将 LDAP 列入该选项的适用协议(Protocols 字段包含 FTP、LDAP、TFTP)。LDAP 查询返回的数据本身是文本性质的(LDIF 格式),因此--use-ascii可以用于确保相关场景下采用文本处理路径。从源码结构看,LDAP 相关实现位于 lib/ldap.c 与 lib/openldap.c,该选项的文本语义与这些协议的纯文本数据性质一致。
4.2 Win32 平台的 stdout 文本模式
文档特别强调:该选项会导致在 Win32 系统上发送到 stdout 的数据处于文本模式(text mode)。这是--use-ascii在 Windows 平台上的一个平台特定副作用:
- 在 Win32 的 C 运行时中,标准输出默认可能处于文本模式,此时输出流中的
\n会被转换为\r\n; - 若希望 stdout 按原始字节输出(例如下载二进制数据并通过管道交给其他程序),则不应开启
--use-ascii,保持默认的关闭状态。
该行为与 curl 的 Windows 平台适配代码(src/tool_doswin.c、lib/system_win32.c)相关。在 Unix/Linux 系系统上则没有这一区分,stdout 始终按字节原样输出。
五、与关联选项的协同与区别
文档的 See-also 字段指向两个关联选项:
5.1--crlf
--crlf将本地换行符转换为 CRLF。二者的关系体现在 lib/ftp.c 的传输数据转换逻辑中:crlf与prefer_ascii都会触发 CRLF 转换路径,但语义不同:
--use-ascii:请求服务器以 ASCII 模式传输(FTP 的TYPE A、TFTP 的netascii),是协议层的模式协商;--crlf:仅要求 curl 在本地数据流上做换行转换,不涉及与服务器的模式协商。
详情见 docs/cmdline-opts/crlf.md。
5.2--data-ascii
--data-ascii用于 HTTP POST 的-d数据家族,指定数据以 ASCII 方式发送。它与--use-ascii共享 "ascii" 命名空间,但属于完全不同的功能域(HTTP 请求体编码 vs FTP/TFTP 传输模式)。详情见 docs/cmdline-opts/data-ascii.md。
六、实战要点总结
- 什么时候用
--use-ascii:通过 FTP/TFTP 传输纯文本文件(脚本、配置、文档)且需要服务器端换行符转换时。二进制文件(压缩包、图片、可执行文件)切勿使用,必须保持默认的二进制模式。 - URL 后缀是等效的替代写法:
- FTP:
;type=A(ASCII)、;type=I(二进制,默认)、;type=D(目录列表); - TFTP:
;mode=netascii(文本)、;mode=octet(二进制,默认); - 注意 URL 中的后缀需要引号包裹,避免 shell 把
;解释为命令分隔符。
- FTP:
- 底层机制:命令行开关与 URL 后缀最终都汇聚到 libcurl 内部的
prefer_ascii状态(经CURLOPT_TRANSFERTEXT设置,见 lib/setopt.c),再由各协议实现消费——FTP 发送TYPE A命令并执行 CRLF 转换,TFTP 在 RRQ/WRQ 中携带netascii模式。 - 平台差异:在 Win32 上开启该选项还会把 stdout 切换为文本模式,管道重定向二进制数据时需注意。
- 布尔开关特性:作为
ARG_BOOL类型,它支持--no-use-ascii显式关闭,适合在配置文件或脚本中做开关控制(参见 docs/cmdline-opts/config.md 中布尔选项的通用写法)。
七、参考与延伸阅读
- 选项定义文档:docs/cmdline-opts/use-ascii.md
- 命令行参数解析:
C_USE_ASCII分支见 src/tool_getparam.c,参数表注册见 src/tool_getparam.c - 配置结构体字段:src/tool_cfgable.h
- 工具层→库层选项对接:src/config2setopts.c
- 库层选项处理(
CURLOPT_TRANSFERTEXT):lib/setopt.c - FTP
;type=URL 解析:lib/ftp.c - FTP 换行转换逻辑:lib/ftp.c
- TFTP netascii 模式选择:lib/tftp.c、URL
;mode=解析:lib/tftp.c - 关联选项文档:docs/cmdline-opts/crlf.md、docs/cmdline-opts/data-ascii.md
- 帮助文本输出实现:src/tool_listhelp.c
【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考