207

Any unix:

I have the following cmd line which works fine.

rsync -avr -e ssh /home/dir user@example.com:/home/

But I need to set it up now to rsync to a remote server that only has an FTP server on it. How do I go about that?

I looked at the rsync help but quickly got lost (I don't do this stuff very often).

Good Person
  • 359
  • 6
  • 18
bumperbox
  • 2,273
  • 3
  • 16
  • 13
  • 21
    This is akin to asking how to use HTTP over IRC, or how to use FTP over SMTP... – Juliano Nov 11 '09 at 12:26
  • 2
    Maybe you could explain some of your reasoning for wanting to do this, then we can help you come up with a viable solution. – James Jul 05 '11 at 21:06
  • 1
    essentially i was trying to automate a backup from a shared hosting server, and didn't understand how rsync worked. i have moved to a vps now, and don't have the limitation of ftp anymore – bumperbox Jul 05 '11 at 21:58
  • Duplicity is your god: http://scie.nti.st/2013/4/13/using-duplicity-for-full-server-backup-on-ubuntu-12-dot-04/ – user956584 Feb 27 '15 at 15:02
  • If **deployment** is, what's on your mind, and you don't mind NodeJS, check out [dploy](https://github.com/lucasmotta/dploy), lazy and works well with git – Frank Nocke Dec 12 '16 at 14:42
  • On many systems, there is some type of user level file system that uses FTP under the covers. Ubuntu I got curlftpfs. Mac you can use Finder => Go => Connect to server and put in a ftp://xxx URI. Then you can use rsync as if it is going between two local directories. – pedz May 27 '19 at 00:18

18 Answers18

181

rsync isn't going to work for you for the reasons others have mentioned. However, lftp and ncftp both have "mirror" modes that will probably meet your needs.

I use this to push stuff from my local directory to a ftp or sftp web host:

lftp -c "set ftp:list-options -a;
open ftp://user:password@your.ftp.com; 
lcd ./web;
cd /web/public_html;
mirror --reverse --delete --use-cache --verbose --allow-chown  
--allow-suid --no-umask --parallel=2 --exclude-glob .svn"
JamesThomasMoon
  • 633
  • 2
  • 5
  • 23
easel
  • 2,229
  • 2
  • 12
  • 4
  • 3
    lftp is very nice. another one i just found out about is `wput` which has built-in bandwidth limiting. – karmakaze Jul 17 '13 at 06:46
  • I would suggest to add "set ftp:use-mdtm-overloaded true" in order to set file mtime to the same as original (should one uses the other way round, viz. no reverse). – Marc Rechté May 29 '20 at 12:43
  • See also https://stackoverflow.com/a/70058912/9134997 for command line options of lftp. There are really good parameters for syncing data! – Michael Hutter Nov 21 '21 at 22:26
131

As written by easel, lftp is a good tool.

I suggest you to parametrize the script, and make use of the

exclude-glob

options, that excludes filenames using the glob feature (*,? ..) of your shell:

#!/bin/bash    
HOST="your.ftp.host.dom"
USER="username"
PASS="password"
FTPURL="ftp://$USER:$PASS@$HOST"
LCD="/path/of/your/local/dir"
RCD="/path/of/your/remote/dir"
#DELETE="--delete"
lftp -c "set ftp:list-options -a;
open '$FTPURL';
lcd $LCD;
cd $RCD;
mirror --reverse \
       $DELETE \
       --verbose \
       --exclude-glob a-dir-to-exclude/ \
       --exclude-glob a-file-to-exclude \
       --exclude-glob a-file-group-to-exclude* \
       --exclude-glob other-files-to-exclude"

Warning: make sure that the target directory exists, otherwise the cd command will fail, so operation including deleting trees of files will take place at wrong directory (root)!

I have updated script so that --delete option is disabled by defaut, enable it by uncommenting the DELETE= command.

Rafa Viotti
  • 172
  • 9
GabrieleV
  • 1,629
  • 1
  • 12
  • 13
  • Helped me a great bunch. But I had to remove the "set ftp:list-options -a;" which where messing stuff up. – mat Nov 16 '10 at 20:33
  • Brilliant response GabrieleV - That script is brilliantly constructed! Thanks –  Jan 18 '11 at 01:52
  • 1
    Is there something like this that does the same thing over SFTP (FTPS?)? – trusktr Mar 14 '12 at 02:52
  • 1
    I would do this before `cd $RCD`, so as to prevent a-script-with-a-typo from accidentally deleting files from the wrong directory: `set cmd:fail-exit yes`. (It seems `lftp` doesn't notice that it has actually exited, until you issue the next command.) — And before `cd $LCD` I'd do this (in the local shell, that is, at the top of the scrip): `set -eu`. – KajMagnus Jun 28 '12 at 21:05
  • 3
    Actually, the first time I run my script, I had not yet created the remote directory, so the script failed to CD into that non-existing dir. Then the script started to `mirror`, and thus `--delete`:d files from the wrong dir. (But I copied them back again, so in that case it didn't matter. Perhaps it matters for someone else.) – KajMagnus Jun 28 '12 at 22:09
  • 1
    As well as following @KajMagnus' advice about using 'set -eu' and 'cd $LCD', add 'mkdir -p $LCD' before 'cd $LCD' - that way you can be sure that the directory exists and you're in it. – Paul Gear Mar 19 '13 at 22:04
  • Two additional notes: * lftp tries TLS on its own (check with lftp -d). You may want to add `set ssl:verify-certificate false;` for self-signed certs. * Rate limit can be applied via `set net:limit-total-rate 25000:0;` which limits the download to 25 kb/s (flip around the : for uploads) – Sebastian J. May 04 '14 at 14:59
  • @truskt You can use sshfs to mount an SFTP (SSH) session on your drive and use actual rsync with the mounted SFTP session. `sshfs remoteuser@remoteserver:remotedirectory mountpoint` like `sshfs root@192.168.2.123:/home/root /mnt/sftp` – EkriirkE May 09 '14 at 09:48
  • This is nice. The only edit I'd suggest is to move the host server (== machine), username and password in a ~/.netrc file. – c.gutierrez Mar 13 '15 at 01:53
  • I parameterized your script (so that it could be called from an external script). But overall great script and it worked right out of the box!! Cheers! – skidadon May 25 '15 at 17:47
  • Good advice from @KajMagnus. Sometimes it is necessary to add more protection. I've found some combinations of lftp commands can result in errors that are caught but not immediately. Specifically, parallelization options like `set mirror:parallel-transfer-count 5;` and `set mirror:use-pget-n 3;` seem to spin up threads that don't catch errors right away. I've found it necessary to run the command once with all but the `mirror` command, and only if that succeeds to run again with `mirror --max-errors=1`. Odd that error trapping isn't synchronous but was not for me. – Chris Johnson Sep 13 '17 at 20:49
87

You don't. rsync can't do that for you, it is a protocol of its own and doesn't work over FTP.

You might, however, want to try csync. IIRC it provides rsync-like behaviour over HTTP. I can't comment on whether it works over FTP, you'll have to try it.

Peter Mortensen
  • 2,319
  • 5
  • 23
  • 24
Martin M.
  • 6,428
  • 2
  • 24
  • 42
  • 3
    Looking at the [csync web page](http://www.csync.org/), it supports sftp but there's no mention of support for plain ftp. – Keith Thompson Jul 11 '14 at 02:06
28

Depending of what you're actually trying to do, another completely different approach could be use curlftps to mount a ftp folder, and then maybe rsync the two "local" folders.

The installation is different depending on your distro so I can't generalize on that, but you need to installfuse and curlftpfs (prolly Debian already has fuse install by default), then:

  1. sudo apt-get install curlftpfs

  2. Make sure the fuse module is loaded (modprobe fuse)

  3. sudo curlftpfs ftp.yourserver.com /path/to/ftp/folder/ -o user=username:password,allow_other

Note that there's no space after the last comma (it's not a typo!). If you're satisfied with that or don't want to make that every time, you can add it to your fstab (usually in /etc/fstab):

curlftpfs#user:password@ftp.yourserver.com /path/to/ftp/folder/ fuse auto,user,uid=1000,allow_other 0 0

In that case, you have to make sure the fuse module is loaded before.

Be advised though, of two things:

  • That the developer dropped the project one or two years ago, so I don't know how usable/stable for the time being.
  • If the password contains a weird character curlftpfs could fail (maybe you can do something with the .netrc).
  • FTP Fuse and rsync is closest to the question but clearly insane on anything but a small set of small files. – Steve-o Sep 23 '11 at 21:03
  • 1
    Why would it be insane? By default rsync stat()s, it doesn't compare the contents. That can be done by ls -l with an ftp client. – ptman Dec 30 '11 at 11:21
  • I actually tried this (via rsnapshot) and it didn't work, each file returned and error, showing that rsync couldn't create a link. So using lftp in conjunction with rsnapshot did the trick – Konstantin Pereiaslov Feb 11 '13 at 04:25
  • Flawless on 14.04 LTS; an additional tip: when you're ready to unmount your FTP site simply use `umount DIR` where `DIR` was your `/path/to/ftp/folder` above. – Joe Aug 04 '15 at 15:42
  • This will probably leave files that are currently being written by the ftp when rsync access them, in a partial-transferred state on the destination. – sivann Dec 16 '15 at 04:55
  • 2
    2017, and this still works! Honestly the easiest way to copy files from a FTP site enmasse. Mount locally, then rsync as if it were local – td512 May 11 '17 at 05:45
  • This is not a good plan if the goal is to use rsync's built-in diff algorithm to save bandwidth, as that requires rsync to communicate with the server using a custom protocol. It can do this via SSH but not via FTP. (This is why rsync doesn't work with plain SFTP, only full SSH.) – Leo Izen Dec 24 '17 at 23:18
17

There is weex...

Weex is an utility designed to automate the task of remotely maintaining a web page or other FTP archive. It will synchronize a set of local files to a remote server by performing uploads and remote deletes as required.

Johan
  • 795
  • 2
  • 7
  • 13
  • 3
    Works like charm! You running it like this: `$ weex yourFTPconfigName` Here is manual http://www.linuxcertif.com/man/1/weex/ – sobi3ch Jan 30 '15 at 14:48
12

For what it appears you are trying to do, you could also use wget.

wget -m ftp://username:password@domain.com

12

rsync does not work over ftp. On the remote side it needs either the rsync daemon or a shell that it can call rsync from. Ftp generally allows you to call a few commands and rsync is not one of them. There are other tools meant for automating ftp tasks like "lftp".

Ian Kelling
  • 2,661
  • 6
  • 23
  • 21
8

This seems like a good and free fit: https://savannah.gnu.org/projects/ftpsync/

pauska
  • 19,532
  • 4
  • 55
  • 75
  • 1
    Given the steaming pile of *don't-touch-with-a-ten-foot-pole* SourceForge has become lately, perhaps you should update the link to the [project's webpage](https://savannah.gnu.org/projects/ftpsync/). – HopelessN00b Feb 22 '16 at 00:32
5

I am using GVFS/FTP. I mount my remote FTP servers with gigolo. As they are seen as local directories almost anything working on local files works. rsync is designed to compute file hashes remotely to compare files without transferring them, but doing that with virtual files transfers the files anyway. unison and freefilesync normally work well but I met a problem when they want to rename a file thy uploaded, no problem downloading. This could be a problem with gvfs 1.6.1.

Papou
  • 51
  • 1
  • 1
5

You can use curlftpfs to mount ftp and use rsync after http://linux.die.net/man/1/curlftpfs

shaftmx
  • 51
  • 1
  • 1
  • Welcome to ServerFault! This may be a good start, but some more technical detail as to why this is a better approach, and possibly a mock up on how to do it, might be reasonable. – Scott Pack Dec 09 '12 at 22:11
4

rclone is a nice piece of software that does directory synchronization over ftp and many other protocols including cloud storage providers (Amazon S3, Dropbox, Google Drive). It can synchronize to/from any combination of local or remote storage.

To setup an ftp remote follow these instructions.

Once that is done, the sync operation is:

rclone sync /home/dir FTP_REMOTE:/home --progress 
bernie
  • 375
  • 1
  • 3
  • 12
3

Jonas S's solution can be useful depending on the circumstance, for example if you have a high download speed and slow upload, checking the files on the server might be relatively faster than uploading files unnecessarily.

You probably want to use CurlFTPFS, though: http://packages.ubuntu.com/search?suite=default&section=all&arch=any&searchon=names&keywords=curlftpfs

Although, generally, it is better to use a regular FTP client altogether instead of rsync.

Peter Mortensen
  • 2,319
  • 5
  • 23
  • 24
2

I don't believe you will be able to do this, the server you are trying to Rsync to will only have an FTP server running, it will not understand the commands that Rsync is sending it.

If the reason you want to do this is that you only have access to port 21, but you have control of the server, you can change the port Rsync listens on, on the server, but this is obviously only useful if you don't want to use FTP on that port.

Sam Cogan
  • 38,158
  • 6
  • 77
  • 113
2

If you want to automate the task then use lftp as you can create a script as some people have posted above, you can script it all really easily to your liking, if your looking for a one time solution (i.e. you need download an entire website via ftp / move it to another server) use ncftp, its simple, install it if its not already installed:

apt-get install ncftp

or

yum install ncftp

(sorry non debian/red hat based distros..)

once installed, open ncftp in the terminal then type:

open -u ftpusername ftp.thedomain.com

It'll ask you for the password, enter it, and then:

get -R /home/remotewebsite/public_html/ /home/localwebsite/public_html/

It'll do the rest pf the work for you.. good luck

Lucas Kauffman
  • 16,818
  • 9
  • 57
  • 92
desdecode
  • 21
  • 1
1

Using “sitecopy” or “mirror” can save you lots of bandwidth.

They both handle efficient incremental update.

Kan-Ru Chen
  • 121
  • 2
  • sitecopy: https://packages.debian.org/stretch/sitecopy / https://directory.fsf.org/wiki/Sitecopy – myrdd Oct 08 '18 at 13:52
0

There's also wput:

wput --timestamping --reupload --dont-continue source-files ftp://target.host/dir

The username and password are read from ~/.netrc. Otherwise, if you're not particularly concerned with security, you may supply them as ftp://username:password@target.host.

Ole Wolf
  • 400
  • 1
  • 4
  • 13
0

I made own command-line tool for that: ftpsync

Why? Because it's simple and elegant, other tools require a lot of dependencies, sometimes compiling, sometimes doesn't work (e.g. lftp on MacOs High Sierra). Ftpsync is written in pure Python, doesn't require 3rd party libs and it's small, you can just include the file in your project.

Usage: cd to your project directory and type:

ftpsync user:pass@ftp.address.url/remote/dir --delete

--delete stands for deleting remote files which don't exist locally.

If you don't want to sync but just run raw ftp command use:

ftpsync -c '...'

It's useful for some simple operations like sending file and rename it:

ftpsync -c 'PASV; TYPE I; STOR some_file.ext; RNFR some_file.ext; RNTO some_file_renamed.ext'
Cory Knutson
  • 1,866
  • 12
  • 20
  • Stumbled upon this due to same reason as others do. A need for a good sync utility over FTP protocol. Your tool looks good, but I couldn't put it to use, since my requirement is to download from remote and sync with local. I want to avoid downloading files that are already downloaded. On local I do a processing on downloaded files which makes it differ; that should be skipped next time FTP script runs. At the moment hard time finding a solution. – anup Mar 16 '18 at 13:11
  • Yes, actually it's one-way sync. – superdario128 Mar 19 '18 at 22:48
-7

Install sftp and then you can use rsync.

I use the following one.

rsync --delete --times --recursive --perms --owner --group --verbose --progress --stats -e ssh root@192.168.0.100:/folder1/ /folder2/
Peter Mortensen
  • 2,319
  • 5
  • 23
  • 24
Rajat
  • 3,329
  • 21
  • 29