Skip to main content

Execute an FTP command (ftp.cmd)

Declaration​

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

Parameters​

  • URL
    String. Remote FTP URL, including the username and password. For directory operations, use a directory URL ending in /.
  • cmd
    String. A single FTP protocol command, such as MKD test. A table of commands is not supported.
  • connectTimeoutSec
    Number, optional. Connection timeout in seconds. Default: 10. This does not limit the total duration of the request.

Returns​

  • result
    String or nil. On success, returns the received data, which may be an empty string. With a directory URL, this is usually a directory listing, not the FTP command's status code or control connection reply. Returns nil on failure.
  • err
    String or nil. On failure, a text description of the error. On success, no second value is returned, so the receiving variable is nil.

Description​

Sends a command to an FTP server for operations such as creating directories. These operations act on files or directories on the server.

The command runs before changing to the directory specified in the URL. Relative paths are based on the default directory after login; for example, MKD uploads/test creates test inside uploads under that directory. Do not rely on the URL path to change the command's working directory. Paths in commands are sent directly, without URL percent-decoding.

MKD usually creates only one directory level, so the parent directory must already exist. The operation may fail if the directory already exists, the account lacks permission, or the server does not support the command. To create multiple levels, call the function separately for each directory, from parent to child.

In the current implementation, any command text containing uppercase LIST or NLST is not sent; only the default request for the URL is performed. This also applies when those substrings occur in a directory name. Therefore, NLST does not switch to a names-only listing, and the arguments in LIST -a have no effect.

After executing the command, the function still requests the data at the URL; with a directory URL, it also retrieves a directory listing. If that listing or the data connection subsequently fails, the directory may already have been created, but the function still returns nil and an error message.
This function may yield; other threads may run before it returns.

Simple example​

Put the username and password in the URL. The format is as follows (brackets indicate optional parts):

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

If the username or password contains @, :, or /, escape them as %40, %3A, or %2F, respectively. Other characters that are invalid in a URL can be percent-encoded. For example, with username havonz and password 11@@22, create test in the default directory after login:

local result, err = ftp.cmd("ftp://havonz:11%40%[email protected]/", "MKD test", 10)
if result == nil then
sys.alert("Creation failed: " .. tostring(err))
else
sys.alert("Created successfully")
end

Advanced example​

Create demo and then demo/logs; neither should exist yet. Stop if any step fails. Previously created directories are not automatically deleted.

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("Creation failed " .. path .. ": " .. tostring(err))
return
end
end

sys.alert("Directories created")

Note: The code above uses sys.alert, a function from another chapter.