🏠

Automatically sync files to a device upon USB connection

I prefer not to connect my (Tolino) E-Reader to the internet. Instead, I sync my files via USB. To simplify this process, I created a script that automatically transfers all files from a specific folder to the USB device as soon as it’s plugged in. This is done with a udev rule, which is triggered whenever the USB device is connected. As it’s not recommended to mount drives within udev rules, the udev rule will invoke a systemd service which will do the mounting (via a bash script) instead.

  1. Find the idVendor and idProduct of your USB device by connecting the device via USB, and then using a tool such as lsusb from the usbutils package. lsusb should give you an output similar to this: Bus 001 Device 006: ID 0a12:3456 Rakuten Kobo Inc. tolino. The 0a12 corresponds to the idVendor, the 3456 to the idProduct.
  2. Create /etc/udev/rules.d/tolino.rules with the following contents (change the idVendor and idProduct):

    ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="0a12", ATTRS{idProduct}=="3456", RUN+="/bin/systemctl start tolino"
  3. Reload your udev rules with udevadm control –reload-rules && udevadm trigger
  4. Save the following bash script, e.g. to /home/<user>/.local/bin

    #!/bin/bash
    
    # Needed for udev rule
    export XAUTHORITY=$HOME/.Xauthority
    export DISPLAY=:0
    
    sudo -u <user> DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus" /usr/bin/notify-send "Syncing tolino..."
    sudo modprobe usb-storage
    echo "Waiting until /dev/sda is visible"
    while [ ! -e /dev/sda ]; do
       sleep 1
       echo -n "."
    done
    
    while ! dd if=/dev/sda bs=2048 count=1 of=/dev/null 2>/dev/null; do sleep 1; done # wait until filesysstem detected
    [[ -d /mnt/tolino ]] || mkdir /mnt/tolino # create dir if it’s not existing
    mount /dev/sda /mnt/tolino
    
    cp –no-preserve=mode /path/which/should/be/synced/to/usb/device/* /mnt/tolino/Books/ && rm /path/which/should/be/synced/to/usb/device/*
    
    echo "Unmounting tolino..."
    umount /mnt/tolino
    
    sudo -u <user> DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus" /usr/bin/notify-send "Finished syncing tolino!"
  5. Set the executable flag: chmod +x /path/to/script/from/step/4
  6. Create /etc/systemd/system/tolino.service with the following contents:

    [Unit]
    Description=mount usb device 
    [Service]
    Type=forking
    ExecStart=/path/to/script/from/step/4
    [Install]
    WantedBy=multi-user.target
  7. Reload the systemd daemon: systemctl daemon-reload
  8. Test and enjoy it 😀 Every time you connect your e.g. E-Reader via USB, the udev rule will trigger the systemd service, which will run the script to mount the device, sync the files, and unmount the device once done. You should also receive desktop notifications when the sync process starts and finishes. Enjoy your reading!