6

I'm having trouble getting a script run by udev to run in the background on usb insert.

My udev rule seems to work, since it definitely calls the script, but no matter what I do, I can't get bash script to run in the background, so it blocks.

For Reference:

My udev rule:

ATTRS{idVendor}=="125f", ATTRS{idProduct}=="db8a", SYMLINK+="usb/adata%n", ENV{XAUTHORITY}="/home/abe/.Xauthority", ENV{DISPLAY}=":0", OWNER="abe", RUN+="/home/abe/bin/usb-adata_udev.sh"

My bash script:

#!/bin/bash

if [[ $ACTION == "add" ]]; then
    # I've tried many variations on this, none seem to work
    (su abe /bin/bash -c "/home/abe/Documents/Programs/USB\ Sync/usb-in.sh") &
fi

if [[ $ACTION == "remove" ]]; then
    /home/abe/Documents/Programs/USB\ Sync/usb-out.sh &
fi

the background script:

#!/bin/bash

#echo $ACTION > "/home/abe/Desktop/test.txt"

if [[ ! -d "/media/abe/ABE" ]]; then
    # for testing
    sleep 10
    #udisksctl mount -b /dev/usb/adata1 &> "/home/abe/Desktop/test.txt" 
    #rsync --update /media/abe/ABE/Files/db.kdbx /home/abe/Documents/db.kdbx
    echo "FINISHED" >> "/home/abe/Desktop/test.txt"
fi

The usb is doesn't get mounted by nautilus until the 10 seconds are done, and the udisksctl command gives me the error Error looking up object for device /dev/usb/adata1 when uncommented, which makes me think that the udev rule hasn't even finished making the symlinks.

Note that the script works just fine when I run it from my terminal and not udev

1 Answers1

7

RUN could be used only for short tasks.

RUN{type}

...
       This can only be used for very short-running foreground tasks.
       Running an event process for a long period of time may block all
       further events for this or a dependent device.
   Starting daemons or other long running processes is not appropriate
   for udev; the forked processes, detached or not, will be
   unconditionally killed after the event handling has finished.

source: man udev

You may use disown that will detach that previous process from the current shell.

#!/bin/bash

if [[ $ACTION == "add" ]]; then # I've tried many variations on this, none seem to work (su abe /bin/bash -c "/home/abe/Documents/Programs/USB\ Sync/usb-in.sh") & disown fi

if [[ $ACTION == "remove" ]]; then /home/abe/Documents/Programs/USB\ Sync/usb-out.sh & disown fi

It is similar case as Write files in usb when connect by /etc/udev/rules.d/ and may be you to look to this too https://askubuntu.com/a/635477/26246 by Fëamarto, nice recursive trick which wait till partition is mounted.


Update

udev changed much lately in these years. It is become part of systemd and more confined. Here are the current options:

user.dz
  • 48,105
  • 1
    Do you expect the disown to make it work? I am in a very similar situation, calling the script with & in RUN+=, and the script runs a nohup bash -c "stuff" & disown, yet the command stuff dies immediately, if at all started. – Gauthier Oct 14 '19 at 09:43
  • @Gauthier, no sure, udev changed much lately in these years. Let me update my question, at least give a hint. – user.dz Oct 14 '19 at 09:57