Linux / Unix: lftp Command To Mirror Files and Directories

How do I mirror files from remote FTP server using lftp command? How do put the entire directory from a local disk to a remote FTP server (reverse mirror) using lftp command under Linux and Unix like operating systems?
Tutorial details
Difficulty Easy
Root privileges No
Requirements lftp ftp client

lftp command is a file transfer program that allows sophisticated FTP, HTTP and other connections to other hosts. lftp command has a builtin mirror which can download or update a whole directory tree. There is also a reverse mirror (mirror -R) which uploads or updates a directory tree on the server. The mirror can also synchronize directories between two remote servers, using FXP if available. The syntax is:

mirror options
mirror -c
mirror -R

A note about file transfer/mirror option and data security

Please note that lftp can support several file access methods using FTP, FTPS (secure option), HTTP, HTTPS (secure option), HFTP, FISH, SFTP and file. The secure option only works if OpenSSL is installed and configured on your system which is a default these days. I suggest you only use FTPS/HTTPS or use FTP/HTTP over VPN.

Example: How to mirror files from a remote ftp server (get files)

First, you need to connect to the remote ftp server using the following syntax:
Type username and password:

lftp> user

Sample outputs:


Type ls command to see a list of files:

lftp> ls

Sample outputs:

-rw-r--r--    1 80       www      36809419 Jun 24 23:59 2012-06-24.log.gz
-rw-r--r--    1 80       www      100912271 Jun 25 23:59 2012-06-25.log.gz
-rw-r--r--    1 80       www      102926055 Jun 26 23:59 2012-06-26.log.gz

To mirror all of the above files in the current directory, enter:

lftp> mirror

With mirror lftp command you can specify source directory to local target directory. If target directory ends with a slash, the source base name is appended to target directory name. Source and/or target can be URLs pointing to directories. The syntax is:

lftp> mirror source target


lftp> mirror logs/ /data/wwwlogs

I highly recommend that you start mirror job with resume option. This make sure if ftp mirror was failed due to network connection it will only download partial file

lftp> mirror -c source target


lftp> mirror --continue

To download only newer files (-c won’t work):

lftp> mirror --only-newer


lftp> mirror -n

You can speed up ftp mirror operation by downloading files in parallel (-P(capital P) or --parallel=N) using the following syntax:

lftp> mirror -P

To download 10 files in parallel, enter:

lftp> mirror --parallel=10

You can use pget to transfer every single file:

lftp> mirror -c  --use-pget-n=10

Example: How to reverse mirror files to a remote ftp server (put files)

You need to pass -R or --reverse option to do reverse mirror i.e. put all files from a local disk to a remote ftp server including sub-dirs and all files in it. In this example reverse mirror /home/project/website/version5/ to a remote ftp server called
First, you need to connect to the remote ftp server using the following syntax:
Type username and password:

lftp> user

Sample outputs:


Change local directory to /home/project/website/version5/:

lftp> lcd /home/project/website/version5/

Sample outputs:

lcd ok, local cwd=/home/project/website/version5

To upload, enter:

lftp> mirror -R

OR set local directory and remote upload directory as follows:

lftp> mirror -R /home/vivek/projects/website/version10 /var/www/html

When using -R, the first directory is local and the second is remote. If the second directory is omitted, base name of first directory is used. If both directories are omitted, current local and remote directories are used. If target directory ends with a slash (except root directory) then base name of source directory is appended. To quit from ftp session type:

lftp> quit

A complete list of lftp mirror command options

Taken from the man page:

            -c, --continue      continue a mirror job if possible
            -e, --delete        delete files not present at remote site
                --delete-first       delete old files before transferring new ones
                --depth-first        descend into subdirectories before transferring files
            -s, --allow-suid         set suid/sgid bits according to remote site
                --allow-chown   try to set owner and group on files
                --ascii         use ascii mode transfers (implies --ignore-size)
                --ignore-time        ignore time when deciding whether to download
                --ignore-size        ignore size when deciding whether to download
                --only-missing  download only missing files
                --only-existing download only files already existing at target
            -n, --only-newer    download only newer files (-c won't work)
                --no-empty-dirs don't create empty directories (implies --depth-first)
            -r, --no-recursion  don't go to subdirectories
                --no-symlinks   don't create symbolic links
            -p, --no-perms      don't set file permissions
                --no-umask      don't apply umask to file modes
            -R, --reverse       reverse mirror (put files)
            -L, --dereference   download symbolic links as files
            -N, --newer-than=SPEC    download only files newer than specified time
                --on-change=CMD      execute the command if anything has been changed
                --older-than=SPEC    download only files older than specified time
                --size-range=RANGE   download only files with size in specified range
            -P, --parallel[=N]  download N files in parallel
                --use-pget[-n=N]     use pget to transfer every single file
                --loop          loop until no changes found
            -i RX, --include RX include matching files
            -x RX, --exclude RX exclude matching files
            -I GP, --include-glob GP include matching files
            -X GP, --exclude-glob GP exclude matching files
            -v, --verbose[=level]    verbose operation
                --log=FILE      write lftp commands being executed to FILE
                --script=FILE        write lftp commands to FILE, but don't execute them
                --just-print, --dry-run   same as --script=-
                --use-cache          use cached directory listings
            --Remove-source-files    remove files after transfer (use with caution)
            -a             same as --allow-chown --allow-suid --no-umask

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 13 comments so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf ncdu pydf
File Managementcat cp mkdir tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
13 comments… add one
  • kiranjith Aug 6, 2012 @ 18:12

    great stuff

  • Pothi Kalimuthu Aug 13, 2012 @ 9:41

    Very interesting tool. Can’t wait to test it out.

  • charles Dec 27, 2012 @ 3:51

    Great tutorial!

  • tim May 5, 2013 @ 21:40

    Very usefull to make backups from my minecraft server when i am not @ home


  • Usama Aziz Oct 2, 2013 @ 22:22

    Great tutorial! Very simple :)

  • Alexey Kostin Jan 13, 2014 @ 22:54

    The -p option is --no-perms (not --parallel[=N]). I think you mean -P. Check this, please.

  • Nabyl Jan 28, 2014 @ 12:20

    Great tutorial,
    Quick question, I’m trying to reverse mirror specific subfolder via cronjobs
    I’m using :
    lftp sftp://username:password@host -e “cd path1; lcd /path2; mirror -Rn ; quit”
    but it get stuck on files that keeps being changed. For instance /var/log/message will keep lftp stuck on transferring at 99%
    it there a work around to skip files that are still being open ?
    Thanks in advance

  • Indian Kumara Apr 1, 2014 @ 20:57

    THanks! works very well.

  • Marcos Jan 31, 2017 @ 10:15

    Well done. Thanks for posting!

  • Talha Feb 17, 2017 @ 20:23

    The man page says that capital “P” is for parallel and small “p” is for permissions. Can you please verify?

  • Jeff Mar 21, 2017 @ 3:15

    You made an error with this command:

    lftp> mirror -p

    the -p switch will actually make it ignore user permissions rather than run in parallel. You are thinking of -P which is to run parallel.

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum