Why can't I run adb via udev? I am writing a bash script that will run upon plugging my Android 6.0.1 phone into my Ubuntu 16.04 laptop. I am stuck at the point where the script runs fine when I execute it manually from a terminal session, but it fails when I try to have it automatically run via a udev rule.

The content of /etc/udev/rules.d/99-android.rules is:

ACTION=="add", ATTRS{idVendor}=="04e8", ATTRS{idProduct}=="6860",MODE="0666", RUN+="/data/personal/backup/backup_galaxya5_start"


The content of /data/personal/backup/backup_galaxya5_start is:

#!/bin/bash
sudo -u marc echo /data/personal/backup/backup_galaxya5 | at now


The content of /data/personal/backup/backup_galaxya5 is a whole heap of things, but it essentially boils down to:

adb start-server
adb push /data/download/rsync4android/rsync.bin /data/local/tmp/rsync &gt;&gt; "$LOGFILE"
adb shell chmod 755 /data/local/tmp/rsync &gt;&gt; "$LOGFILE"
adb shell 'exec &gt;/data/local/tmp/rsyncd.conf &amp;&amp; echo address = 127.0.0.1 &amp;&amp; echo port = 1873 &amp;&amp; echo "[root]" &amp;&amp; echo path = / &amp;&amp; echo use chroot = false &amp;&amp; echo read only = false' &gt;&gt; "$LOGFILE"
adb shell /data/local/tmp/rsync --daemon --no-detach --config=/data/local/tmp/rsyncd.conf --log-file=/proc/self/fd/2 &amp; &gt;&gt; "$LOGFILE"
adb forward tcp:6010 tcp:1873
rsync -av --exclude .thumbnails/ "rsync://localhost:6010/root/sdcard/DCIM/" "$TARGETDIR" &gt; "$RSYNCLOGFILE"


As I said, running this when the phone is plugged in from a terminal works without any problems. However, when I plug the phone in to have the script run automatically, the following happens:


The udev rule picks up the fact that the phone was plugged in and executes /data/personal/backup/backup_galaxya5_start.
That file uses the at command the schedule the actual backup script to run.
The actual backup script runs and starts the adb server.
The backup script is then unable to copy the rsync.bin file to the phone.
The subsequent adb commands are failing as well.


At some point I even changed the script to pickup the failed "adb push" command and then do a "adb kill-server", however this also did not help.

I would like to know what I am missing in order to make this script work when called from the udev rule.
I've given a try to http://www.joescat.com/linux/android_rules.html
but it failed to start adb server, don't know why

In "/etc/udev/rules.d/51-android.rules":

SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4ee7", ACTION=="add", RUN+="/usr/bin/rehtet"


/usr/bin/rehtet (nohup and &amp; and disown won't work, "at now" work):

#!/bin/bash
echo "/usr/bin/adb shell ls &gt;/tmp/rehadb.log" | at now


And the last 3 lines in the rehadb.log showed:

...
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(5037), sin_addr=inet_addr("127.0.0.1")}, 16


Finally, I fixed it (maybe there are bad side effects):

edit "/lib/systemd/system/systemd-udevd.service", change "IPAddressDeny=any" into "IPAddressDeny="
run "systemctl daemon-reload"   "service udev restart"
to enable udev script (gnirehtet / adb) to access 127.0.0.1:5037