我无法使用 udev 运行 shell 脚本,该脚本会在外部驱动器通过 USB 连接时将硬盘驱动器备份到外部驱动器。除了实际调用 rdiff-backup 之外,一切正常。udev 检测到硬盘驱动器并正确调用脚本。脚本运行并正确显示桌面通知,但 shell 脚本从未运行 rdiff-backup,并且脚本运行到立即结束,从未备份驱动器。我已经编辑了我的 sudoers 文件,以便脚本具有适当的权限。
我知道 Cuttlefish 可以让我相对轻松地执行此操作,但为了学习一般方法,我更愿意学习使用 Linux 中内置的工具来自己完成此操作。任何帮助都将不胜感激。
我的 udev 规则定义如下:
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1f75", ATTR{idProduct}="0621", RUN+="/home/nam/.scripts/backup_root_and_home_folders_to_external_drive.sh"
我的shell脚本如下:
#!/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."
答案1
删除该行sudo su
。它将启动一个永不返回的新 root shell,这就是为什么此后的任何命令都不会被执行。
最重要的是,授予自己sudo su
无需密码即可执行操作的权限存在严重的安全风险,在现实环境中不应这样做。
答案2
我注意到一些预期的问题:
应该匹配条件检查一下任务
ATTR{idProduct}="0621"
那应该是一个平等ATTR{idProduct}=="0621"
。该规则将在安装分区之前运行,甚至可能在读取分区表之前运行。
刚插入闪存盘的示例:
$ 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)
该规则以 USB 设备节点为目标
/devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0
,以分区节点为例更加方便/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
。添加KERNEL
节点名称并用于ATTRS
规则匹配。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"
即使使用以前的 mod,规则也可能在安装之前运行,因此您需要延迟。另外,UDEV 无法运行长时间的任务,因此如果
rdiff-backup
没有很快完成,它将被 UDEV 杀死。请参阅man udev
为了解决这些问题,请生成新进程然后放弃它。请参阅以下答案:为什么如果我使用,我的 udev 规则会运行
udevadm trigger
,但在启动时却不运行?