Why FTP ls > filename makes an empty file on an HMI panel

5 min read · Published November 9, 2026

The stock command-line FTP client has no > redirection. It reads ls > filename as ls remote-path local-file, so it asks the panel to list a path named > and opens your local file before any data arrives, leaving 0 bytes. Type ls . listing.txt instead and confirm the replies 150 then 226.

The stock command-line FTP client has no > redirection. Its ls command takes two arguments: a remote directory to list, and a local file to write the listing into. When you type ls > filename, the client reads > as the remote path and filename as the local file. It creates your file first, asks the panel for a directory named >, the panel refuses the path, and no listing data ever arrives. You are left with a 0-byte file that looks like a panel-side failure. The repair takes under 2 minutes: ls . listing.txt, and the reply codes in a debug trace show which side failed.

What the client does with your line

The command reference for the stock client defines ls as ls [remote-directory] [local-file]. The first argument becomes the path in the request the client sends to the panel, the second is the local file the client writes the listing into. Nothing at the ftp prompt interprets >, >> or |; those belong to a shell. A few advanced clients implement redirection on their own, which is where the copied line usually comes from.

Token you typed How the client reads it What happens
ls the list command accepted
> remote directory path the panel has no such path and answers 550
filename local file for the listing created before any data exists, 0 bytes written

The file appears on your disk because the client opens the local file when the command runs. It stays at 0 bytes because the listing transfer never started. The panel answered the command, so the fault sits in what the client sent.

What each symptom points to

  • A file that appears at once and holds 0 bytes points at the client: it created the local file and never received listing data.
  • A 550 reply right after the command points at the remote path argument, the literal >.
  • A 150 reply followed by a hang, or a 425 or 426, points at the data connection, usually a PC firewall blocking the connection the panel opens back to the client in active mode.
  • A 530 at login points at the user or password configured in the panel.
  • A 150 then 226 with a filled file points at a working capture.

Fixes that cannot change the result

  • A different file name or folder. The file was created, so local write permission works and the name was free to use.
  • ASCII versus binary mode. A listing is a text transfer on the data channel, and the mode governs byte translation; there are no bytes to translate.
  • A panel power cycle or a project reload. The panel answered the command.
  • More redirection, >> or |. The stock client passes those characters along as arguments too.

Capture the listing with the right arguments

  1. Open the session with debug on: ftp -d followed by the panel address, for example ftp -d 192.168.10.71.
  2. Log in with the user and password configured in the panel's FTP settings.
  3. Run ls . listing.txt. The dot is the remote path, the current folder; listing.txt is the local file.
  4. To capture one folder, put its name first: ls project listing.txt.
  5. Watch the trace for 150 followed by 226; the whole exchange takes under 10 seconds on a healthy panel.
  6. Close with bye, then check the file size on the PC within 5 seconds of the prompt returning.

For a quick look with no file involved, ls . - prints the listing on screen in clients that accept a hyphen as the local file, and you can copy the text from there.

Example: from 0 bytes to a full listing

Scenario: a maintenance PC at 192.168.10.40, a panel at 192.168.10.71, and a folder on the panel holding 14 log files with 12-character names.

First run, the copied line: ls > listing.txt. With debug on, the trace shows the client sending NLST > and the panel answering 550 with a message about a missing path. The message text varies between servers; the code is what counts. listing.txt on the PC measures 0 bytes.

Second run, the correct line: ls . listing.txt. The trace shows NLST ., then 150 as the data connection opens, then 226 when it closes. The file measures 196 bytes. The arithmetic: 14 entries x 14 bytes per line, a 12-character name plus the two line-ending characters, gives 196 bytes. A second run also returns 196 bytes, a difference of 0 bytes, so the capture is stable. Both runs together took under 30 seconds.

Read the trace when the file is still empty

Start the client with debug on whenever a capture comes back empty and read the replies. RFC 959, the FTP specification, defines the reply codes used here, including 150, 226, 425, 426, 530 and 550.

Trace Action
550 right after the list command The remote path was rejected. Correct the first argument.
150, then a hang, or 425 or 426 The data connection is blocked, usually a PC firewall stopping the connection the panel opens back to the client in active mode. Allow the client through the firewall on the test network and retest.
150 then 226, file still 0 bytes The transfer finished and the folder holds no entries this account can see. List the parent folder and check the account's folder access in the panel FTP setup.
530 at login The user or password is wrong. Confirm the credentials configured in the panel.

A login that succeeds and a command that gets an answer tell you the FTP service on the panel is alive. The same split applies when an HMI panel web server stops responding while FTP still works; the two services fail separately.

Run it unattended with a script

Once the interactive run works, put the same lines in a script file: the user name, the password, ls . listing.txt, and bye, in that order. Run it as ftp -s:cmds.txt followed by the panel address. The commands run in the order they appear, so the capture lands the same way every time; a scheduled run of 3 commands finishes in under 15 seconds. If the folder holds screen images you want on a board, displaying FTP images in an industrial dashboard is the next step once the listing is clean.

Keep the test on an isolated network segment and keep any firewall change off the production network. Keep credentials out of script files on shared PCs, the same care you take when you serve LAN share images to a web app safely.

Recommendation: capture panel listings with ls . listing.txt at the prompt, and move to ftp -s:cmds.txt once the run is stable. Treat every 0-byte output as a failed run until the trace shows 150 then 226. If the listing feeds something the floor reads, settle the screen choice first with live factory data display: signage or dashboard.

Questions

What is the difference between ls and dir in the FTP client?

ls sends NLST to the server and returns bare file names. dir sends LIST and returns the detailed form with permissions, sizes and dates, one line per entry. Both take the same two arguments, so dir . listing.txt writes the detailed listing into your local file the same way ls does.

Does switching ASCII or binary mode fix the empty file?

No. A directory listing travels on the data channel as text, and the transfer mode governs how bytes are translated, so it has no effect on how the arguments parse. Switch to binary mode when you later download project files, images or logs that are not plain text.

Can I avoid opening the PC firewall for the data connection?

Yes. In active mode the panel opens the data connection back to your PC, and that connection back to the client is what a client-side firewall blocks. A client with a passive mode option opens the data connection to the server instead, so nothing has to be allowed through the firewall on the PC side. Keep any firewall change limited to the test network.

How do I run the listing from a script and know it worked?

Put the username and password lines, then ls . listing.txt, then bye in cmds.txt, and run ftp -s:cmds.txt followed by the panel address. Keep bye on the last line, because the client stops reading the script once the session ends. Check the file size after every run and treat 0 bytes as a failed run.

Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.

Keep reading

Build your signAsk for a quote