{"id":2033,"date":"2021-09-11T14:24:00","date_gmt":"2021-09-11T11:24:00","guid":{"rendered":"https:\/\/joseph.zikusooka.com\/?p=2033"},"modified":"2021-09-12T03:36:09","modified_gmt":"2021-09-12T00:36:09","slug":"how-to-automatically-backup-your-data-to-an-external-usb-disk-on-linux","status":"publish","type":"post","link":"https:\/\/joseph.zikusooka.com\/?p=2033","title":{"rendered":"How to automatically backup your data to an external USB disk on Linux"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>One of the most critical roles that any Systems Administrator must perform on a regular basis is that of running backups for an organization. These days, most big and medium sized offices use Network Attached Storage servers to quickly perform backups on their networks. However, for small offices with limited IT budgets, a DIY solution which uses a simple USB external hard drive is a viable option.<br><br>In this setup, the resident &#8220;IT guy&#8221; is assigned the task of backing up data. This could be from a handful of desktops\/laptops, or a central backup server.  However, the problem with this setup is that they often will forget to plug in the disk or even initiate the manual backup process, leading to a very unreliable backup scheme.<\/p>\n\n\n\n<p>In this article, I will guide you on how to set up a cheaper, reliable and automated backup scheme. All the operator has to do is to plug in the USB external hard disk any time, and the backup process commences immediately.<br><br>This solution takes advantage of a bash script that is triggered once the USB hard disk is inserted into the computer desktop or laptop&#8217;s USB ports. The trigger mechanism is handled by udev rules via a systemd unit as will be shown below.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Operating system: Linux<br>Desktop: GNOME &#8211; mainly for notification purposes<br>Username: erica (Must have permissions to run &#8216;sudo&#8217;)<br>Data: \/home<br>Partition is NOT encrypted. See &#8216;cryptsetup&#8217; tool<\/p>\n\n\n\n<p>Create the following backup script. Save it and make it executable:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vim \/opt\/backup_2_usb_disk.sh\nchmod 755 \/opt\/backup_2_usb_disk.sh<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>\n#!\/bin\/sh\n# Variables\nNORMALUSER=erica\nVOLUMENAME=BACKUP\nUSB_DISK_PARTITION=$USB_DISK_PARTITION1\nMOUNTPOINT=\/run\/media\/$NORMALUSER\/$VOLUMENAME\nRSYNC_OPTIONS=\"-aAXvH\u201d\n# Excludes 4 \/home\nEXCLUDE_FILE_4_HOME_DIR=\/tmp\/exclude_dirs_in_home_dir\nEXCLUDE_DIRECTORIES_IN_HOME_DIR=\"Videos\"\nNOTIFY_CMD=\/usr\/bin\/notify-send \nNOTIFY_ICON=\/usr\/share\/icons\/gnome\/scalable\/devices\/media-zip-symbolic.svg\nNOTIFY_TITLE=\"\"\n\n\n# Functions\nnotice () {\nsu -l $NORMALUSER -c \"$NOTIFY_CMD -i $NOTIFY_ICON $NOTIFY_TITLE '$@'\"\n}\n\ndisable_automount () {\nsu -l $NORMALUSER -c \"dbus-launch gsettings set org.gnome.desktop.media-handling automount false\"\nsu -l $NORMALUSER -c \"dbus-launch gsettings set org.gnome.desktop.media-handling autorun-never true\"\n}\n\nsync_data () {\nsudo rsync $RSYNC_OPTIONS --delete \"$1\" \"$2\"\n}\n\nmount_partition () {\n# Create mountpoint if it does not exist\n&#91; -d $MOUNTPOINT ] || mkdir -p $MOUNTPOINT\n# Mount drive\nmount $USB_DISK_PARTITION $MOUNTPOINT\nSTATUS_MOUNT=$?\nif &#91; \"$STATUS_MOUNT\" != \"0\" ];\nthen\nnotice \"ERROR: mount $USB_DISK_PARTITION $MOUNTPOINT failed\"\nexit 1\nfi\n}\n\nbackup_thinkpad () {\n# Create backupdir directory\n&#91; -d $MOUNTPOINT ] || mkdir $MOUNTPOINT\n\n# Start of backup\nnotice \"Backup Started\"\n\n# \/home\necho $EXCLUDE_DIRECTORIES_IN_HOME_DIR | tr \" \" \"\\n\" &gt; $EXCLUDE_FILE_4_HOME_DIR\nsleep 3\nrsync $RSYNC_OPTIONS --delete --exclude-from=$EXCLUDE_FILE_4_HOME_DIR \/home\/ $MOUNTPOINT\/home\/\nrm -f $EXCLUDE_FILE_4_HOME_DIR\n\n# other partitions\n}\n\numount_partition () {\numount $USB_DISK_PARTITION\nSTATUS_UMOUNT=$?\nif &#91; \"$STATUS_UMOUNT\" != \"0\" ];\nthen\nnotice \"ERROR: umount $USB_DISK_PARTITION failed\"\nexit 1\nfi\n}\n\nenable_automount () {\nsu -l $NORMALUSER -c \"dbus-launch gsettings set org.gnome.desktop.media-handling automount true\"\nsu -l $NORMALUSER -c \"dbus-launch gsettings set org.gnome.desktop.media-handling autorun-never false\"\n}\n\n\n# Process the following routines\ndisable_automount\nmount_partition\nbackup_thinkpad \numount_partition\nenable_automount \n\n# Notice of completion\nsleep 10\nnotice \"Backup completed successfully\"<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Start\/Stop service<\/h2>\n\n\n\n<p>Create the systemd unit file:<br>\/etc\/systemd\/system\/backup-usb-disk.service and add the following:<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=USB Portable Drive\n\n&#91;Service]\nUser=root\nType=oneshot\nEnvironment=DISPLAY=:0\nExecStart=\/opt\/backup_2_usb_disk.sh\n\n&#91;Install]\nWantedBy=multi-user.target<\/code><\/pre>\n\n\n\n<p><strong>NOTES:<\/strong><br>Reload systemd daemon i.e. &#8216;systemctl &#8211;system daemon-reload&#8217;<br>It is not necessary to enable or start the above unit at this time<br>since that will be done by the udev rule below.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">UDEV rules<\/h2>\n\n\n\n<p>Create the udev rules file: \/etc\/udev\/rules.d\/97-backup-usb-disk.rules and add the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ACTION==\"add\", ATTRS{idVendor}==\"0bc2\", ATTRS{idProduct}==\"2400\", SYMLINK+=\"disk\/by-id\/$env{ID_NAME}_$env{ID_SERIAL}\", RUN+=\"\/usr\/bin\/systemctl start backup-usb-disk.service\"\n\nACTION==\"remove\", ATTRS{idVendor}==\"0bc2\", ATTRS{idProduct}==\"2400\", RUN+=\"\/usr\/bin\/systemctl stop backup-usb-disk.service\"<\/code><\/pre>\n\n\n\n<p><strong>NOTES:<\/strong><br>To find your USB disk Vendor and Product ID, run the command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>udevadm info -a -p $(udevadm info -q path -n \/dev\/sdX) | grep -B2 -i -e idvendor -e idproduct<\/code><\/pre>\n\n\n\n<p><br>Change &#8216;X&#8217; to suit your setup<br>Run the command &#8216;udevadm control &#8211;reload&#8217; to reload the rules<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>That&#8217;s it! Now when ever, the USB external disk is plugged into the USB port, the backup script will be triggered. You can extend the above mentioned backup script to not only back up other partitions beyond just the \/home in our example, but also email the operator whenever the process completes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction One of the most critical roles that any Systems Administrator must perform on a regular basis is that of running backups for an organization. These days, most big and medium sized offices use Network Attached Storage servers to quickly perform backups on their networks. However, for small offices with limited IT budgets, a DIY [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2018,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"footnotes":""},"categories":[19],"tags":[],"class_list":["post-2033","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorial"],"_links":{"self":[{"href":"https:\/\/joseph.zikusooka.com\/index.php?rest_route=\/wp\/v2\/posts\/2033","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/joseph.zikusooka.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/joseph.zikusooka.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/joseph.zikusooka.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/joseph.zikusooka.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2033"}],"version-history":[{"count":1,"href":"https:\/\/joseph.zikusooka.com\/index.php?rest_route=\/wp\/v2\/posts\/2033\/revisions"}],"predecessor-version":[{"id":2034,"href":"https:\/\/joseph.zikusooka.com\/index.php?rest_route=\/wp\/v2\/posts\/2033\/revisions\/2034"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/joseph.zikusooka.com\/index.php?rest_route=\/wp\/v2\/media\/2018"}],"wp:attachment":[{"href":"https:\/\/joseph.zikusooka.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/joseph.zikusooka.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2033"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/joseph.zikusooka.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2033"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}