Edit: There is a part 3 that solves the daemon problem.
It has been about a year since my first blog post about syncing Microsoft’s OneDrive cloud storage on Linux. The last time around, I used RCLONE, which required a more hands-on approach. I have found a new tool that I think is better because it can sync automatically in the background without scripting or manually hacking. It is aptly called onedrive that you can find on Github.
Its name might suggest that Microsoft finally ported their Windows and Mac clients to Linux, but, unfortunately, that is not the case. I would still like to see this happen, and if there is ever a time for Microsoft to do it, it is probably now.
Let me briefly explain how I have installed and configured the
onedrive tool to suit my needs. Thanks to good default values, it is
straightforward, and you might not need any configuration at all.
(I wonder how I managed to not find this tool a year ago)
The documentation is extensive, and
onedrive is available on many
Linux distributions through the package manager.
On Fedora, which I am currently using, the installation was as simple as:
sudo dnf install onedrive
If you do not have any particular wishes and only want everything in
your OneDrive account synced, the default settings are all you
need. It is how I did my first synchronization. Like on Windows, files
are stored in a "OneDrive" folder, but you can change it with the
sync_dir configuration option.
⚠️ IMPORTANT Carefully read the documentation about this setting to avoid data loss from changing the value after initial sync. ⚠️
To try it out, I started with a single folder.
onedrive --synchronize --single-directory Code
I tested with a second one, and then I triggered a full sync.
onedrive --synchronize --verbose
While the sync was happening, I created a custom configuration for some fine-tuning. Here is what I ended up with:
skip_dir = "Documents" skip_file = "*.obj|*.a|*.o|*.tmp|*.pdb|*.cache|*.class" # Every 10 minutes monitor_interval = "600"
My "Documents" folder is actually called "Files". "Documents" on Windows is used by games and applications to dump saves or other application configuration. Nothing I want to be interspersed in my "real" files, hence the separation. On Linux, I do not need my save-games, so I excluded that folder from the sync. The same goes for intermediary files from code compilation. You could also go at it from another angle and provide an allow-list of directories to sync.
Because I do not change my data much on other devices or through the Office online applications while I use my computer simultaneously, I increased the automatic full-sync from five to ten minutes. That should be good enough for me. If I need immediate syncing, I can always trigger it from the command line.
Note that this is only an issue for syncing from the Cloud to the PC.
The other way around,
onedrive uses inotify to detect
changes to files and syncs them immediately to OneDrive when you edit
The next thing I have done is to create symlinks from the default "Music", "Pictures", etc. folders to the "OneDrive" equivalents. This way, the Nautilus bookmarks still work.
rmdir Documents ln -s OneDrive/Files Documents rmdir Pictures ln -s OneDrive/Pictures Pictures
Make sure that you have backed up your files before deleting the folders.
The last thing I did was enable the startup of
onedrive when I log
in to my computer. There are several options, for example, to install
onedrive as a system daemon controlled by Systemd. Although I am the
only person using my computer, I feel like this is a user-centric
application that should run only in the user’s context with the user’s
specific configuration. Therefore, I invested a bit more time
configuring a Systemd daemon as per this manual.
Create the OneDrive configuration:
$ cat .config/onedrive/config sync_dir = "/home/rlo/OneDrive" skip_dir = "Documents" skip_file = "*.obj|*.a|*.o|*.tmp|*.pdb|*.cache|*.class" # Every 10 minutes monitor_interval = "600"
Create the Systemd configuration:
First, copy the service file provided by default after installation.
sudo cp /usr/lib/systemd/system/onedrive@.service /usr/lib/systemd/system/onedrive-rlo@.service
Modify according to your user configuration. All I have done is
%i occurrences with my user name. The most important
part is the value passed to
--confdir. In my case I have a custom
configuration in the default location where
onedrive looks anyway,
so my changes are basically a waste. It’s just to highlight what you
must change. Maybe you want to store your configuration in a different
location, and this is where you do it.
$ cat /usr/lib/systemd/system/onedrive-rlo@.service [Unit] Description=OneDrive Free Client for rlo Documentation=https://github.com/abraunegg/onedrive After=network-online.target Wants=network-online.target [Service] ExecStart=/usr/bin/onedrive --monitor --confdir=/home/rlo/.config/onedrive User=rlo Group=users Restart=on-failure RestartSec=3 RestartPreventExitStatus=3 [Install] WantedBy=multi-user.target
Enable the daemon:
systemctl --user enable onedrive-rlo@rlo systemctl --user start onedrive-rlo@rlo
Unfortunately, this is where it all falls apart. I am not able to
onedrive as a daemon.
$ systemctl --user enable onedrive-rlo@rlo Failed to enable unit: Unit file email@example.com does not exist
I cannot explain it, and I could not find a solution. Systemd seems to be aware of the file, though.
$ systemctl list-unit-files UNIT FILE STATE VENDOR PRESET ... onedrive-rlo@.service disabled disabled onedrive@.service disabled disabled
It does not work with the file that I copied to use as the basis
either. What I have done as a workaround instead is starting
onedrive through a cron job.
$ crontab -e @reboot /usr/bin/onedrive --monitor --confdir="/home/rlo/.config/onedrive"
There is one important thing to note about startup.
onedrive needs a
while to initialize. You should not expect it to pick up changes
directly after you logged in immediately. Give it some time before you
do anything. Data exchange with Windows works nicely if you keep that
in mind. On the other hand, it seems like downloading changes is