2

I'm having trouble using udev to run a shell script that backs up my hard drives to an external drive whenever the external drive is connected via USB. Everything works except the actual call to rdiff-backup. The udev detects the hard drive and calls the script properly. The script runs and displays the desktop notifications properly, but rdiff-backup is never run by the shell script and the script runs to end immediately without ever backing up the drives. I've already edited my sudoers file so that the script has appropriate permissions.

I am aware that Cuttlefish would allow my to perform this action relatively easily, but in the interest of educating myself on the general method, I'd much prefer to learn to use the tools already built in to Linux to accomplish this on my own. Any help would be greatly appreciated.

My udev rules is defined as:

ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1f75", ATTR{idProduct}="0621", RUN+="/home/nam/.scripts/backup_root_and_home_folders_to_external_drive.sh"

and my shell script is as follows:

#!/bin/bash
#sudo su

export DISPLAY=:0
export XAUTHORITY=/home/nam/.Xauthority

logger "Backing up root and home directories to external drive..."

###BACKUP ROOT DIRECTORY
#Issue system notification for backup begin
sv=$(date "+%T")
msgvar="Backing up directory / to external drive started at "
notif=${msgvar}${sv}
sudo -u nam DISPLAY=":0.0" notify-send -t 1000 "$notif"
#notify-send -t 1000 "$notif" 
logger "$notif"

#sleep 5
#Start backup of / directory
st=$SECONDS
#sudo rdiff-backup -v6 --force --exclude /sys --exclude /run --exclude /media --exclude /proc --exclude /home / /media/nam/BACKUP1/root
sudo su
/usr/bin/rdiff-backup -v6 --exclude /sys --exclude /run --exclude /media --exclude /proc --exclude /home / /media/nam/BACKUP1/root
#logger "$ok"

#Issue system notification for backup end
sv=$(date "+%T")
stt=$SECONDS
et=$(($stt - $st))
#notify-send -t 1000 "Backup of directory / completed at $sv. 
#Process took $et seconds."
sudo -u nam DISPLAY=":0.0" notify-send -t 1000 "Backup of directory / completed at $sv. 
Process took $et seconds."


###BACKUP HOME DIRECTORY
#Issue system notification for backup begin
sv=$(date "+%T")
msgvar="Backing up directory /home to external drive started at "
notif=${msgvar}${sv}
#notify-send -t 1000 "$notif" 
sudo -u nam DISPLAY=":0.0" notify-send -t 1000 "$notif"


#Start backup of /home directory
#sudo rdiff-backup -v6 --force /home/ /media/nam/BACKUP1/home/
sudo su
sudo /usr/bin/rdiff-backup -v6 /home/ /media/nam/BACKUP1/home/


#Issue system notification for backup end 
sv=$(date "+%T")
stt=$SECONDS
et=$(($stt - $st))
#notify-send -t 1000 "Backup of directory /home completed at $sv. 
#Process took $et seconds."
sudo -u nam DISPLAY=":0.0" notify-send -t 1000 "Backup of directory /home completed at $sv. 
Process took $et seconds."

2 Answers2

2

Remove the line sudo su. It starts a new root shell that never returns and that is why any command after that is not being executed.

On top of that granting yourself a permission to do sudo su without password is a serious security risk and should not be done in a real world environment.

sмurf
  • 4,680
0

I could notice few expected problems:

  1. Should be match condition check this assignment ATTR{idProduct}="0621" that should be an equality ATTR{idProduct}=="0621" .

  2. That rule will run before mounting the partitions and may be even before reading the partition table.

    Example with flash disk just pluged:

    $ udevadm monitor -u
    monitor will print the received events for:
    UDEV - the event which udev sends out after rule processing
    
    UDEV  [8850.369941] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1 (usb)
    UDEV  [8850.374279] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0 (usb)
    UDEV  [8850.378578] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4 (scsi)
    UDEV  [8850.380505] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4/scsi_host/host4 (scsi_host)
    UDEV  [8851.373706] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4/target4:0:0 (scsi)
    UDEV  [8851.373727] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4/target4:0:0/4:0:0:0 (scsi)
    UDEV  [8851.377944] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4/target4:0:0/4:0:0:0/scsi_disk/4:0:0:0 (scsi_disk)
    UDEV  [8851.380841] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4/target4:0:0/4:0:0:0/bsg/4:0:0:0 (bsg)
    UDEV  [8851.382182] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4/target4:0:0/4:0:0:0/scsi_generic/sg2 (scsi_generic)
    UDEV  [8851.382563] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4/target4:0:0/4:0:0:0/scsi_device/4:0:0:0 (scsi_device)
    UDEV  [8851.399453] add      /devices/virtual/bdi/8:16 (bdi)
    UDEV  [8852.542377] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4/target4:0:0/4:0:0:0/block/sdb (block)
    UDEV  [8853.591178] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4/target4:0:0/4:0:0:0/block/sdb/sdb2 (block)
    UDEV  [8853.591724] add      /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4/target4:0:0/4:0:0:0/block/sdb/sdb1 (block)
    

    That rule targets the USB device node /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0 where it is more convenient to target the partition nodes example /devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host4/target4:0:0/4:0:0:0/block/sdb/sdb1. Add KERNEL node name and use ATTRS for rule match.

    ACTION=="add", KERNEL="sdb?", SUBSYSTEM=="usb", ATTRS{idVendor}=="1f75", ATTRS{idProduct}=="0621", RUN+="/home/nam/.scripts/backup_root_and_home_folders_to_external_drive.sh"
    
  3. Even with previous mod, the rules may run before mounting so you need a delay. Another thing, UDEV can't run long tasks, so if rdiff-backup didn't finish shortly it will be killed by UDEV. See man udev

    To solve these, spawn new process then disown it. See as in this answer: Why do my udev rules run if I use udevadm trigger, but NOT at boot time?

user.dz
  • 48,105
  • 1
    You have equality and assignment backwards, according to man udev, "==" compares for equality and "=" assigns a value to a key. – Lingnik Mar 28 '17 at 04:10
  • @Lingnik Thank you, I should always recheck my words :) as English is not my native lang. – user.dz Mar 28 '17 at 08:31