资讯详情

curl `--quote`(-Q)完全指南:向 FTP/SFTP 服务器发送自定义命令

📅 2026/9/10 3:58:40 | 华诺云谱 👁 阅读
curl `--quote`(-Q)完全指南:向 FTP/SFTP 服务器发送自定义命令
curl--quote-Q完全指南向 FTP/SFTP 服务器发送自定义命令【免费下载链接】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--quote短选项-Q是 curl 命令行中用于向 FTP 或 SFTP 服务器发送任意原始命令的开关它让你能够在文件传输之外执行删除、改名、建目录、改权限等服务器端操作并精确控制这些命令在传输前、传输中还是传输后执行。读完本文你将掌握--quote的三种执行时机传输前/后/CWD 之后、失败容忍前缀*的语义、FTP 原始命令语法要求以及 SFTP 下 curl 自行解释的 12 类受支持命令与文件名转义规则并能通过CURLOPT_QUOTE/CURLOPT_PREQUOTE/CURLOPT_POSTQUOTE在 libcurl 编程中复用同样能力。选项速览--quote的完整命令行元数据定义在仓库的 docs/cmdline-opts/quote.md 中字段值说明Long--quote长选项名Argcommand需要一个命令字符串参数Short-Q短选项别名HelpSend command(s) to server before transfer在传输前向服务器发送命令ProtocolsFTP SFTP仅对 FTP 与 SFTP 协议生效Categoryftp sftp归类于 FTP/SFTP 类别Added5.3自 curl 5.3 起提供Multiappend可重复指定多次给出的命令按顺序追加执行基本用法示例来自原文档curl --quote DELE file ftp://example.com/foo该命令会在访问ftp://example.com/foo之前先向 FTP 服务器发送DELE file即删除名为file的文件然后再执行后续的传输操作。由于Multi: append你可以在一次命令行中重复出现多个--quote以及-Qcurl 会按出现顺序依次追加执行curl -Q DELE old.log -Q RMD olddir ftp://example.com/FTP命令的执行时机与三种前缀--quote发送的命令默认在传输之前执行。对 FTP 而言更精确的时机是紧随登录后最初的PWD命令之后、改变工作目录之前。原文档明确写道Quote commands are sent BEFORE the transfer takes place (immediately after the initialPWDcommand in an FTP transfer, to be exact).在源码层面这条链路由 lib/ftp.c 中的状态机驱动登录完成后进入FTP_QUOTE状态ftp_state_quote()lib/ftp.c#L1856-L1879从data-set.quote链表中逐条取出命令通过Curl_pp_sendf(data, ftpc-pp, %s, cmd)原样发送给服务器全部命令发送完毕后转入ftp_state_cwd()继续改变工作目录lib/ftp.c#L1917-L1923。通过给命令加前缀可以调整执行时机前缀语义对应 libcurl 选项无前缀传输前执行紧随 PWD 之后CURLOPT_QUOTE-短横线传输成功之后执行CURLOPT_POSTQUOTE加号仅 FTP在 curl 已改变工作目录后、文件传输命令如RETR/STOR/LIST之前立即执行CURLOPT_PREQUOTE三种前缀可以混合使用。例如先建目录、传文件、传完再删除临时文件curl -Q MKD archive -T backup.tar -Q -DELE backup.tar ftp://example.com/这里MKD archive在 curlCWD到目标目录之后、上传之前执行上传成功后-DELE backup.tar才执行删除本地备份对应的远端文件。源码中这三种时机分别对应ftp_state_quote()的三种输入状态FTP_RETR_PREQUOTE/FTP_STOR_PREQUOTE/FTP_LIST_PREQUOTE取data-set.prequote链表lib/ftp.c#L1871-L1874FTP_POSTQUOTE取data-set.postquotelib/ftp.c#L1876-L1878。传输完成后的 postquote 由ftp_done()中的ftp_sendquote(data, ftpc,>if(cmd[0] *) { cmd; /* 去掉星号前缀 */ ftpc-count2 1; /* 该命令允许失败 */ } else ftpc-count2 0; /* 失败即取消整个操作 */见 lib/ftp.c#L1900-L1907。SFTP 实现中则有对应的sshc-acceptfail标志lib/vssh/libssh2.c#L778-L786注释明确说明if a command starts with an asterisk, which a legal SFTP command never can, the command is allowed to fail without it causing any aborts or cancels。由于星号不是合法的 SFTP 命令开头用它作为前缀不会与真实命令冲突。典型用法是尽量删除旧文件删不掉也不影响后续上传curl -Q *DELE old.tar -T new.tar ftp://example.com/FTP 命令语法要求对 FTP 服务器--quote必须发送符合 RFC 959 语法的原始命令。curl 不做本地解释只是把字符串原样去掉前缀后写入控制连接——这也意味着你必须自己保证命令语法正确、参数顺序正确并自行处理服务器返回的状态码语义。例如 RFC 959 定义的常见命令可直接使用DELE path删除文件、RMD path删除目录、MKD path建目录、RNFR/RNTO改名、SITE CHMOD mode path修改权限、ABOR中止等。curl 仅负责传输字符串不校验其是否为合法 FTP 命令。SFTP二进制协议下的本地解释SFTP 是二进制协议与 FTP 完全不同命令不能以文本形式直接发给服务器。因此对 SFTP 而言curl 会在本地解释--quote给出的命令字符串识别出受支持的指令后调用对应的底层 SFTP 操作通过 libssh2 实现执行。源码注释直接说明了这一点lib/vssh/libssh2.c#L828-L832SFTP is a binary protocol, so we do not send text commands to the server. Instead, we scan for commands used by OpenSSHs sftp program and call the appropriate libssh2 functions.也就是说--quote在 SFTP 上支持的命令集模仿了 OpenSSHsftp交互程序的命令风格由sftp_quote()lib/vssh/libssh2.c#L762-L920做命令分发。文件名引号与转义由于命令参数需要被 curl 解析包含空格、反斜杠、单双引号的文件名必须用双引号包裹。双引号内支持以下转义序列转义含义\\字面反斜杠\字面双引号\字面单引号该解析逻辑由 lib/vssh/vssh.c 中的Curl_get_pathname()实现lib/vssh/vssh.c#L203-L288它跳过前导空白识别双引号或单引号包裹的路径段遇到\时只接受\、、三种转义目标其余一律报CURLE_QUOTE_ERROR路径最大长度为 65535 字节#define MAX_PATHLENGTH 65535见 lib/vssh/vssh.c#L201。此外SFTP 路径支持/~相对主目录展开当参数以/~开头时curl 会以登录用户的主目录homedir为前缀拼接路径lib/vssh/vssh.c#L249-L257。例如curl -Q chmod 600 /~/.ssh/config sftp://example.com/会修改服务器上当前用户主目录下.ssh/config的权限。SFTP 受支持命令全表原文档列出了 curl 为 SFTP 支持的全部命令逐条说明如下atime date file设置file的最近访问时间Last Access Time。date可以是各种日期表达式支持范围以curl_getdate(3)为准仓库实现见 lib/parsedate.c。自 7.73.0 起提供。chgrp group file将file的组 ID 设置为group。group为十进制整数 GID。源码中通过curlx_str_number()解析十进制数再经LIBSSH2_SFTP_ATTR_UIDGID标志写入属性lib/vssh/libssh2.c#L1164-L1175。由于 libssh2 需同时设置 UID/GIDcurl 会先stat取得当前属主再做修改lib/vssh/libssh2.c#L1142-L1161。chmod mode file修改file的文件模式位。mode为八进制整数。源码使用curlx_str_octal()解析上限 07777写入LIBSSH2_SFTP_ATTR_PERMISSIONSlib/vssh/libssh2.c#L1176-L1187。注意与 FTP 不同这里无需SITE前缀直接chmod 755 file即可。chown user file将file的属主设置为user。user为十进制整数 UID解析与写入逻辑同chgrplib/vssh/libssh2.c#L1188-L1199。ln source_file target_filesymlink source_file target_file在target_file位置创建指向source_file的符号链接。两者是等价的两种写法源码中将二者归入同一分支lib/vssh/libssh2.c#L856-L872。mkdir directory_name创建名为directory_name的目录lib/vssh/libssh2.c#L873-L879。mtime date file设置file的最近修改时间。date表达式同atime同样参考curl_getdate(3)。自 7.73.0 起提供。pwd返回当前工作目录的绝对路径。SFTP 下 curl 会模拟 FTP 的应答格式向 header 回调输出257 path is current directory.lib/vssh/libssh2.c#L788-L805便于脚本像解析 FTP 一样读取结果。rename source target将source指向的文件或目录改名为targetlib/vssh/libssh2.c#L880-L895。rm file删除file指定的文件lib/vssh/libssh2.c#L903-L908。rmdir directory删除directory目录项前提是该目录为空lib/vssh/libssh2.c#L896-L902。除上述命令外源码还额外识别statvfs pathlib/vssh/libssh2.c#L909-L914遇到无法识别的命令时返回CURLE_QUOTE_ERROR并报错 Unknown SFTP commandlib/vssh/libssh2.c#L916-L919。综合实战示例1. FTP传输前清理旧版本传输后重命名curl -Q DELE app.old \ -T app.jar \ -Q -RNFR app.jar -Q -RNTO app.jar.bak \ ftp://example.com/deploy/上传成功后将远端刚上传的文件改名为备份。2. FTP改变目录后立即执行配合星号容忍失败curl -Q *SITE CHMOD 644 index.html ftp://example.com/保证在 curlCWD到目标目录之后、开始传输之前执行*保证即使服务器不支持SITE CHMOD也不会中止整个操作。前缀可叠加使用。3. SFTP上传前建目录、改权限、设时间戳curl -Q mkdir /~uploads \ -Q chmod 700 /~uploads \ -T report.pdf \ -Q mtime 2026-01-01 00:00:00 /~uploads/report.pdf \ sftp://example.com/4. SFTPpwd 探测当前目录curl -Q pwd sftp://example.com/ -o /dev/null -v配合-v可以看到 curl 模拟的 FTP 风格257应答脚本中可据此解析远端当前目录。在 libcurl 编程中使用--quote对应的编程接口是三个 libcurl 选项它们都接收curl_slist链表命令行前缀libcurl 选项语义无CURLOPT_QUOTE传输前命令CURLOPT_PREQUOTECWD 之后、传输命令之前的命令-CURLOPT_POSTQUOTE传输成功后的命令三个选项的枚举定义位于 include/curl/curl.h#L1261-L1264CURLOPT_QUOTE为CURLOPTTYPE_SLISTPOINT类型其结构体定义见 include/curl/curl.h#L2822 附近的curl_slist。选项赋值逻辑在 lib/setopt.c#L1320-L1339注释分别标注为 List of RAW FTP commands to use after a transferpostquote、prior to RETRprequote与 before a transferquote。此外include/curl/typecheck-gcc.h#L556 还提供了针对该选项的 GCC 类型检查确保传入的是struct curl_slist *。C 语言示例#include curl/curl.h int main(void) { CURL *curl curl_easy_init(); struct curl_slist *cmds NULL; /* 传输前删除旧文件允许失败 */ cmds curl_slist_append(cmds, *DELE old.log); /* 传输成功后把文件改名 */ cmds curl_slist_append(cmds, -RNFR upload.tmp); cmds curl_slist_append(cmds, -RNTO upload.log); curl_easy_setopt(curl, CURLOPT_URL, ftp://example.com/upload.tmp); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_QUOTE, cmds); curl_easy_perform(curl); curl_slist_free_all(cmds); curl_easy_cleanup(curl); return 0; }注意 SFTP 下*前缀的容错同样生效acceptfail但-与前缀仅对 FTP 有意义SFTP 侧使用哪个前缀效果一致统一走sftp_quote()分发。注意事项--quote只对 FTP 与 SFTP 生效对其他协议会被忽略或报错。FTP 下 curl 不解释命令内容务必发送 RFC 959 合法命令SFTP 下命令由 curl 本地解释仅支持上文列出的命令集。默认任一命令失败即中止整个操作需要容错时给命令加*前缀。SFTP 文件名含空格、反斜杠、引号时必须用双引号包裹并使用\\、\、\转义。atime/mtime的日期表达式解析细节可查阅仓库中的 lib/parsedate.c对应 man 手册的curl_getdate(3)。多个--quote可重复出现命令按顺序追加执行Multi: append。【免费下载链接】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),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。