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:

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 >> "$LOGFILE"
adb shell chmod 755 /data/local/tmp/rsync >> "$LOGFILE"
adb shell 'exec >/data/local/tmp/rsyncd.conf && echo address = && echo port = 1873 && echo "[root]" && echo path = / && echo use chroot = false && echo read only = false' >> "$LOGFILE"
adb shell /data/local/tmp/rsync --daemon --no-detach --config=/data/local/tmp/rsyncd.conf --log-file=/proc/self/fd/2 & >> "$LOGFILE"
adb forward tcp:6010 tcp:1873
rsync -av --exclude .thumbnails/ "rsync://localhost:6010/root/sdcard/DCIM/" "$TARGETDIR" > "$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:

  1. The udev rule picks up the fact that the phone was plugged in and executes /data/personal/backup/backup_galaxya5_start.
  2. That file uses the at command the schedule the actual backup script to run.
  3. The actual backup script runs and starts the adb server.
  4. The backup script is then unable to copy the rsync.bin file to the phone.
  5. 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.

2 Answers 2


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 & and disown won't work, "at now" work):

echo "/usr/bin/adb shell ls >/tmp/rehadb.log" | at now

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

bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(5037), sin_addr=inet_addr("")}, 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
  • Hello. Can you tell how this answers the question? I don't think this constitutes even as a partial answer, but I may be missing something here.
    – Firelord
    Jul 6, 2019 at 0:02
  • Another possibility: "Consider using SYSTEMD_WANTS instead of calling (potentially long running or privileged) tasks from udev rules."
    – Jortstek
    Nov 17, 2021 at 23:46

You might try adding adb wait-for-device after adb start-server in the file /data/personal/backup/backup_galaxya5. I have found that the script gets run by udev before the adb deamon can get started. Adding adb wait-for-device blocks until adb is up and your device is registered.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .