FTP isn’t exactly cutting-edge technology. These days, if you control both ends of a connection, you’re probably using scp, SFTP, rsync, or something even fancier. But FTP refuses to die, especially if you are perusing old public FTP servers or talking to retrocomputers. Every now and then, you still need an FTP client. Naturally, there are plenty of graphical clients. But some of us would rather stay at the command line. You could just type ftp, of course. It works, and if you haven’t used it lately, it is probably better than you remember. However, I’ve long been a fan of NcFTP. While some other FTP clients have caught up, it still has unique features that make FTP a lot more productive.
Not Your Father’s FTP
Before maligning the standard ftp command, though, we should point out that it probably isn’t the FTP client you remember from 30 years ago. For example, on openSUSE Tumbleweed, /usr/bin/ftp is really tnftp, a portable version of NetBSD’s enhanced FTP client. Debian uses it too; the ftp package in both Bookworm and Trixie leads you to tnftp. Since current Raspberry Pi OS is based on Debian Trixie, you’ll encounter tnftp there, too. That’s significant because tnftp has already fixed many of the irritations you might associate with old-fashioned FTP.
You get command-line editing, history, and filename completion, things that are also in ncftp. Both understand passive FTP and IPv6. The tnftp client can also retrieve HTTP, HTTPS, and file: URLs, so commands such as:
ftp https://example.com/something.tar.gz
aren’t necessarily typos, although ncftp lacks this ability. But ncftp does have some killer features.
Remember Me?
One of NcFTP’s nicest creature comforts is bookmarks. Connect to a machine, move to a useful directory, and save it:
ncftp /pub/micros> bookmark oldstuff
Then later you can simply type:
ncftp oldstuff
The bookmark can remember more than just the hostname, making frequently used FTP sites feel much more like named resources than anonymous servers you repeatedly have to navigate.
NcFTP also maintains a cache of remote directory listings. If you’ve ever used FTP over a slow link, you know how annoying it is to ask for the same directory listing over and over. NcFTP can often work from what it already knows instead. Neither feature sounds earth-shattering, but together they make an interactive FTP session considerably more pleasant.
Get All The Things
Another difference becomes obvious when you want an entire directory. NcFTP supports recursive transfers:
get -R foo
or:
put -R foo
That seems obvious if you’re accustomed to modern tools, but traditional FTP is fundamentally organized around transferring individual files. NcFTP does the tedious directory walking for you. It also handles resuming interrupted transfers more naturally, something particularly welcome when the file in question is a multi-gigabyte disk image rather than README.TXT. With tnftp, you have to explicitly ask to resume an interrupted file. NcFTP will detect it and, depending on configuration, either resume or, at least, offer to resume the transfer.
Go Away, I’m Busy
NcFTP also has a clever background-transfer system. Commands such as:
bgget giant-file.iso
Hand a transfer to NcFTP’s spooler rather than tying up your interactive session. There are corresponding facilities for uploads. That’s an interesting distinction from simply detaching a shell command. NcFTP knows that this is a transfer job and maintains a queue of FTP work that can be retried and processed independently.
Shell Games
But perhaps the biggest reason to know about NcFTP is that NcFTP isn’t just one program. The package includes commands such as ncftpget, ncftpput, and ncftpls. These perform FTP operations directly from the Unix shell without starting an interactive FTP command interpreter. For example:
ncftpget ftp.example.com /tmp /pub/widget.bin
or:
ncftpput ftp.example.com /incoming widget.bin
This is much nicer in a script than sending commands to ftp using, for example, a here document and automating login with .netrc. For example:
ftp <<EOF open ftp.example.com cd incoming put widget.bin quit EOF
Sure, it works, but any time you send input to an interactive program it is, at best, messy. The ncftpput program expresses what you actually wanted to do in the first place: put this file there. That’s much more Unix-like.
Don’t Do This At Home
None of these conveniences change FTP’s fundamental problem: ordinary FTP is not secure. Usernames, passwords, and data can travel without encryption. If you’re designing a new system and control both ends, you usually have much better choices. But sometimes you don’t control both ends. If FTP is something you run into, ncftp is worth knowing about. Bookmarks, cached directories, recursive and background transfers, and especially the script-friendly companion commands turn an antique protocol into something that feels surprisingly at home on a modern Unix command line.
Of course, just as you can use FUSE to mount an ssh server, you can use ftpfs, to make a remote server look like part of your file system. You never know when FTP is going to crop up.

Lftp> mirror -p
For the win!
Where is the FTP mirror of github?
+1 for lftp. Recursive transfers, queues, pause/resume, concurrent chunked transfers, etc
Surprised it wasn’t mentioned here!
Yeah. lftp is the rsync of ftp. If you need ftp, it is the way to go.
FTP was my go-to file transfer protocol (get it?), until I found out about scp utility. Its super convenient, and its super simple to script when you provide certs along with it.
SSH, I really like it.
FTP was wrapped by UI clients that made it look as if it is http.
But it is a connection with a command channel. Needs a series of commands to grab a file. I suppose, originally someone would telnet into a ftp server, just leave that command connection alive forever, now and then tell it: “Hey connect to that machine over there and push that file”. Possibly a 3rd machine all together.
Then NAT came out, adding hacks to support FTP in active mode. The NAT box has to track every FTP connection and fiddle with the bytes sent/received counters.
There is a lot complexity and features in the FTP protocol, exceeding the simple file-get mechanics, even outside of the client and server.
Windows Explorer (the file browser) made it look like it was just a local folder by typing the address and login as your path. I think it still does. I can’t remember what sort of havoc that did on the server side, but at least it was convenient. You could just give a friend the address and say “here, type this in” and they’d get access to your files.
I used to run a server for myself with a default open login that went to a lagged honeypot account, and the server was pretending it was complying, so they’d try to create folders and upload files and waste time to no effect. That’s because they were spamming whole IP ranges to find FTP servers that respond and once found they’d direct a whole botnet to try and spam the login, which would bog down my DSL. But if they got in the attack stopped while the bot attempted to find out if they can do anything with it.
NetBSD’s command line ftp will work with http and https, plus can easily be scripted. It was in Mac OS X for ages, of course it’s portable to other systems, and it gets regular security updates and other fixes.
This brought back memories of the Old Times, when installing a package on a Unix system meant grabbing a source tarball, unpacking it, compiling, and installing. There were quite a few well known sites that distributed software in source form via anonymouse ftp. I was amused by the host named labrea.stanford. edu. It was a “tar pit”.
Punch cards, Telnet, Gopher, http://FTP..
The article mentions SFTP but neglects to mention the other forms of encrypting FTP. I mean, I get it’ it’s somewhat confusing to understand the difference between FTPS, SFTP, and FTPES, but that doesn’t mean they don’t exist. Using FTP securely has been possible nearly forever now,…
If you have a plethora of files to share with the world publicly, it’s still one of my favorite mechanisms. At least it’s a proper file transfer protocol. While scp is great for personal use to move files between machines you have users on, for public publishing, I’ll take FTP and/or rsync over HTTP any time… (and WEBDAV is still trash).
Hm.. So FTP has multiple, superflous extensions, like Linux has a dozen package managers? ;)
Reading about FTP variants also brings back memories of visiting computer mailboxes.
For file transfer they had used Kermit, XMODEM, YMODEM, ZMODEM..
Why do we even need something like FTP shoehorned on SSH? Just do something like
cat source | ssh user@host 'cat > target'orssh user@host 'cat file' > targetfor same effect.Or just
scp source user@host:/targetandscp user@host:/source targetOr just
scp source user@host:/targetandscp user@host:/source targetthis article made me ponder why i gave up ncftp, because i remember having a strong preference for it towards the end of the last century.
i think what happened is basically that i couldn’t use it at work (i guess i could have, but i would have had to build it from source). So i learned how to use ‘regular’ ftp, which i have found to be mostly the same on every platform. So for example, i learned how to put my credentials in .netrc…and i put macros in there too. And in practice that’s as useful as ncftp’s bookmarks. And the biggest thing is i learned that ftp is amenable to stdin/stdout redirection. So, for example, “(echo cd /testcase; echo put newbuild; echo quit) | ftp testserver” started to make it into my test harnesses. ncftpput or whatever turned out to be entirely redundant.
At the end of the day, it turns out the only thing ncftp really offers is that the UI is a little glossier. Especially, it provided by default a nice status display during downloads…a progress bar and time remaining?? And that was really valuable to me at 14.4kbps, and today i couldn’t care less.