跳到主要内容

FTP 执行命令 (ftp.cmd)

声明​

result, err = ftp.cmd(URL, cmd [, connectTimeoutSec ])

参数​

  • URL
    文本型,FTP 远端地址,账号及密码包含在这一参数中;执行目录操作时应使用以 / 结尾的目录 URL
  • cmd
    文本型,一条 FTP 协议命令,例如 MKD test,不支持传入命令表
  • connectTimeoutSec
    实数型,可选参数,连接超时时间,单位秒,默认 10;不限制整个请求的总耗时

返回值​

  • result
    文本型 或 nil,请求成功时返回收到的数据,可能为空字符串;使用目录 URL 时通常为目录列表,不是 FTP 命令的状态码或控制连接回复;失败时返回 nil
  • err
    文本型 或 nil,失败时返回错误原因文本描述;成功时不返回第二个值,接收变量为 nil

说明​

向 FTP 服务器发送命令,可用于创建目录等操作,操作对象是服务器上的文件或目录。

命令在切换到 URL 指定的目录之前执行。相对路径以登录后的默认目录为基准;例如 MKD uploads/test 在该目录下的 uploads 中创建 test。不要依靠 URL 中的路径改变命令的执行目录;命令中的路径直接发送,不进行 URL 百分号解码。

MKD 通常只创建一级目录,父目录需要已经存在。目录已存在、账号没有权限或服务器不支持相应命令时,都可能失败。创建多级目录需要按父目录到子目录的顺序分别调用。

当前实现只要命令文本包含大写的 LIST 或 NLST,就会跳过发送该命令,仅执行 URL 的默认请求;即使这些片段出现在目录名中也一样。因此 NLST 不会切换成仅文件名列表,LIST -a 的参数也不会生效。

执行命令后仍会请求 URL 对应的数据,使用目录 URL 时还会获取目录列表。如果后续列目录或数据连接失败,目录可能已经创建,但函数仍返回 nil 和错误信息。
该函数可能会让出,在其返回之前,其他 线程 可能会得到运行机会

简单示例​

账号密码写在 URL 中,具体 URL 格式如下(中括号内是可选部分):

ftp://[user:password@]host[:port]/path

账号或密码中包含 @、:、/ 这三个字符可分别用 %40、%3A、%2F 转义(其他在 URL 中非法的字符可使用 URL 百分号编码)。 例如账号 havonz、密码 11@@22,在登录后的默认目录下创建 test:

local result, err = ftp.cmd("ftp://havonz:11%40%[email protected]/", "MKD test", 10)
if result == nil then
sys.alert("创建失败:" .. tostring(err))
else
sys.alert("创建成功")
end

复杂示例​

依次创建 demo 和 demo/logs,两者均应尚不存在。某一步失败就停止,不自动删除此前已创建的目录。

local url = "ftp://havonz:11%40%[email protected]/"

for _, path in ipairs({ "demo", "demo/logs" }) do
local result, err = ftp.cmd(url, "MKD " .. path, 10)
if result == nil then
sys.alert("创建失败 " .. path .. ": " .. tostring(err))
return
end
end

sys.alert("目录创建完成")

注:上述代码中使用了非本章函数 sys.alert。