Commands and files
List files and metadata
Compare human-oriented LIST output with NLST names and standardized MLSD facts.
Every listing uses a data connection. That trips people up constantly. Login works, you type ls, and the prompt sits there forever. Before you reset passwords, fix passive mode or open the passive port range on the firewall.
LIST returns human-readable lines. The format varies by server, so home-grown parsers break easily. NLST gives names only. MLSD returns standardized facts when the server supports it. I check feat first so I know which commands are even available.
If your script assumes MLSD and the server only offers LIST, it will fail on the first deploy. Read feat in staging.
Check what your server offers:
ftp> feat
211-Features:
MLST
MLSD
SIZE
211 End
ftp> mlsd
150 Opening data connection
type=file;size=4812;modify=20260730101522; report.csv
type=dir;modify=20260729120000; archive
226 Transfer complete
If MLSD is missing, you might fall back to classic LIST:
ftp> ls
150 Opening data connection
-rw-r--r-- 1 alice staff 4812 Jul 30 10:15 report.csv
drwxr-xr-x 2 alice staff 64 Jul 29 12:00 archive
226 Transfer complete
Do not split LIST lines on spaces and assume the last word is always the filename. Names with spaces break naive parsers. I have seen scripts grab 2026 as the filename because they split a date field wrong.
Modification time is useful metadata, but it is not proof of content. Two files can share a size and timestamp and still differ. When you need certainty, compare a hash after download.
When login works and listing fails, read the replies around EPSV and 150. Silence after 150 usually means the data TCP connect never completed. A 425 means the server could not open the data path at all.
Run feat, then one listing command on a test host. Note whether the client picked MLSD, NLST, or LIST, and what it did with a filename that contains a space.
Lesson completed